UNPKG

1.16 MBJavaScriptView Raw
1/*! OpenPGP.js v5.0.0-1 - 2021-03-03 - 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
4/**
5 * web-streams-polyfill v2.1.1
6 */
7/// <reference lib="es2015.symbol" />
8const SymbolPolyfill = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?
9 Symbol :
10 description => `Symbol(${description})`;
11
12/// <reference lib="dom" />
13function noop() {
14 // do nothing
15}
16
17/// <reference lib="es2015.core" />
18// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill
19const NumberIsNaN = Number.isNaN || function (x) {
20 // eslint-disable-next-line no-self-compare
21 return x !== x;
22};
23
24const rethrowAssertionErrorRejection = noop;
25
26function typeIsObject(x) {
27 return (typeof x === 'object' && x !== null) || typeof x === 'function';
28}
29function createArrayFromList(elements) {
30 // We use arrays to represent lists, so this is basically a no-op.
31 // Do a slice though just in case we happen to depend on the unique-ness.
32 return elements.slice();
33}
34function ArrayBufferCopy(dest, destOffset, src, srcOffset, n) {
35 new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset);
36}
37function IsFiniteNonNegativeNumber(v) {
38 if (IsNonNegativeNumber(v) === false) {
39 return false;
40 }
41 if (v === Infinity) {
42 return false;
43 }
44 return true;
45}
46function IsNonNegativeNumber(v) {
47 if (typeof v !== 'number') {
48 return false;
49 }
50 if (NumberIsNaN(v)) {
51 return false;
52 }
53 if (v < 0) {
54 return false;
55 }
56 return true;
57}
58function Call(F, V, args) {
59 if (typeof F !== 'function') {
60 throw new TypeError('Argument is not a function');
61 }
62 return Function.prototype.apply.call(F, V, args);
63}
64function CreateAlgorithmFromUnderlyingMethod(underlyingObject, methodName, algoArgCount, extraArgs) {
65 const method = underlyingObject[methodName];
66 if (method !== undefined) {
67 if (typeof method !== 'function') {
68 throw new TypeError(`${method} is not a method`);
69 }
70 switch (algoArgCount) {
71 case 0: {
72 return () => {
73 return PromiseCall(method, underlyingObject, extraArgs);
74 };
75 }
76 case 1: {
77 return arg => {
78 const fullArgs = [arg].concat(extraArgs);
79 return PromiseCall(method, underlyingObject, fullArgs);
80 };
81 }
82 }
83 }
84 return () => promiseResolvedWith(undefined);
85}
86function InvokeOrNoop(O, P, args) {
87 const method = O[P];
88 if (method === undefined) {
89 return undefined;
90 }
91 return Call(method, O, args);
92}
93function PromiseCall(F, V, args) {
94 try {
95 return promiseResolvedWith(Call(F, V, args));
96 }
97 catch (value) {
98 return promiseRejectedWith(value);
99 }
100}
101// Not implemented correctly
102function TransferArrayBuffer(O) {
103 return O;
104}
105// Not implemented correctly
106function IsDetachedBuffer(O) {
107 return false;
108}
109function ValidateAndNormalizeHighWaterMark(highWaterMark) {
110 highWaterMark = Number(highWaterMark);
111 if (NumberIsNaN(highWaterMark) || highWaterMark < 0) {
112 throw new RangeError('highWaterMark property of a queuing strategy must be non-negative and non-NaN');
113 }
114 return highWaterMark;
115}
116function MakeSizeAlgorithmFromSizeFunction(size) {
117 if (size === undefined) {
118 return () => 1;
119 }
120 if (typeof size !== 'function') {
121 throw new TypeError('size property of a queuing strategy must be a function');
122 }
123 return chunk => size(chunk);
124}
125const originalPromise = Promise;
126const originalPromiseThen = Promise.prototype.then;
127const originalPromiseResolve = Promise.resolve.bind(originalPromise);
128const originalPromiseReject = Promise.reject.bind(originalPromise);
129function newPromise(executor) {
130 return new originalPromise(executor);
131}
132function promiseResolvedWith(value) {
133 return originalPromiseResolve(value);
134}
135function promiseRejectedWith(reason) {
136 return originalPromiseReject(reason);
137}
138function PerformPromiseThen(promise, onFulfilled, onRejected) {
139 // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an
140 // approximation.
141 return originalPromiseThen.call(promise, onFulfilled, onRejected);
142}
143function uponPromise(promise, onFulfilled, onRejected) {
144 PerformPromiseThen(PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection);
145}
146function uponFulfillment(promise, onFulfilled) {
147 uponPromise(promise, onFulfilled);
148}
149function uponRejection(promise, onRejected) {
150 uponPromise(promise, undefined, onRejected);
151}
152function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) {
153 return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler);
154}
155function setPromiseIsHandledToTrue(promise) {
156 PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection);
157}
158
159// Original from Chromium
160// https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js
161const QUEUE_MAX_ARRAY_SIZE = 16384;
162/**
163 * Simple queue structure.
164 *
165 * Avoids scalability issues with using a packed array directly by using
166 * multiple arrays in a linked list and keeping the array size bounded.
167 */
168class SimpleQueue {
169 constructor() {
170 this._cursor = 0;
171 this._size = 0;
172 // _front and _back are always defined.
173 this._front = {
174 _elements: [],
175 _next: undefined
176 };
177 this._back = this._front;
178 // The cursor is used to avoid calling Array.shift().
179 // It contains the index of the front element of the array inside the
180 // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE).
181 this._cursor = 0;
182 // When there is only one node, size === elements.length - cursor.
183 this._size = 0;
184 }
185 get length() {
186 return this._size;
187 }
188 // For exception safety, this method is structured in order:
189 // 1. Read state
190 // 2. Calculate required state mutations
191 // 3. Perform state mutations
192 push(element) {
193 const oldBack = this._back;
194 let newBack = oldBack;
195 if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) {
196 newBack = {
197 _elements: [],
198 _next: undefined
199 };
200 }
201 // push() is the mutation most likely to throw an exception, so it
202 // goes first.
203 oldBack._elements.push(element);
204 if (newBack !== oldBack) {
205 this._back = newBack;
206 oldBack._next = newBack;
207 }
208 ++this._size;
209 }
210 // Like push(), shift() follows the read -> calculate -> mutate pattern for
211 // exception safety.
212 shift() { // must not be called on an empty queue
213 const oldFront = this._front;
214 let newFront = oldFront;
215 const oldCursor = this._cursor;
216 let newCursor = oldCursor + 1;
217 const elements = oldFront._elements;
218 const element = elements[oldCursor];
219 if (newCursor === QUEUE_MAX_ARRAY_SIZE) {
220 newFront = oldFront._next;
221 newCursor = 0;
222 }
223 // No mutations before this point.
224 --this._size;
225 this._cursor = newCursor;
226 if (oldFront !== newFront) {
227 this._front = newFront;
228 }
229 // Permit shifted element to be garbage collected.
230 elements[oldCursor] = undefined;
231 return element;
232 }
233 // The tricky thing about forEach() is that it can be called
234 // re-entrantly. The queue may be mutated inside the callback. It is easy to
235 // see that push() within the callback has no negative effects since the end
236 // of the queue is checked for on every iteration. If shift() is called
237 // repeatedly within the callback then the next iteration may return an
238 // element that has been removed. In this case the callback will be called
239 // with undefined values until we either "catch up" with elements that still
240 // exist or reach the back of the queue.
241 forEach(callback) {
242 let i = this._cursor;
243 let node = this._front;
244 let elements = node._elements;
245 while (i !== elements.length || node._next !== undefined) {
246 if (i === elements.length) {
247 node = node._next;
248 elements = node._elements;
249 i = 0;
250 if (elements.length === 0) {
251 break;
252 }
253 }
254 callback(elements[i]);
255 ++i;
256 }
257 }
258 // Return the element that would be returned if shift() was called now,
259 // without modifying the queue.
260 peek() { // must not be called on an empty queue
261 const front = this._front;
262 const cursor = this._cursor;
263 return front._elements[cursor];
264 }
265}
266
267function ReadableStreamCreateReadResult(value, done, forAuthorCode) {
268 let prototype = null;
269 if (forAuthorCode === true) {
270 prototype = Object.prototype;
271 }
272 const obj = Object.create(prototype);
273 obj.value = value;
274 obj.done = done;
275 return obj;
276}
277function ReadableStreamReaderGenericInitialize(reader, stream) {
278 reader._forAuthorCode = true;
279 reader._ownerReadableStream = stream;
280 stream._reader = reader;
281 if (stream._state === 'readable') {
282 defaultReaderClosedPromiseInitialize(reader);
283 }
284 else if (stream._state === 'closed') {
285 defaultReaderClosedPromiseInitializeAsResolved(reader);
286 }
287 else {
288 defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError);
289 }
290}
291// A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state
292// check.
293function ReadableStreamReaderGenericCancel(reader, reason) {
294 const stream = reader._ownerReadableStream;
295 return ReadableStreamCancel(stream, reason);
296}
297function ReadableStreamReaderGenericRelease(reader) {
298 if (reader._ownerReadableStream._state === 'readable') {
299 defaultReaderClosedPromiseReject(reader, new TypeError('Reader was released and can no longer be used to monitor the stream\'s closedness'));
300 }
301 else {
302 defaultReaderClosedPromiseResetToRejected(reader, new TypeError('Reader was released and can no longer be used to monitor the stream\'s closedness'));
303 }
304 reader._ownerReadableStream._reader = undefined;
305 reader._ownerReadableStream = undefined;
306}
307// Helper functions for the readers.
308function readerLockException(name) {
309 return new TypeError('Cannot ' + name + ' a stream using a released reader');
310}
311// Helper functions for the ReadableStreamDefaultReader.
312function defaultReaderClosedPromiseInitialize(reader) {
313 reader._closedPromise = newPromise((resolve, reject) => {
314 reader._closedPromise_resolve = resolve;
315 reader._closedPromise_reject = reject;
316 });
317}
318function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) {
319 defaultReaderClosedPromiseInitialize(reader);
320 defaultReaderClosedPromiseReject(reader, reason);
321}
322function defaultReaderClosedPromiseInitializeAsResolved(reader) {
323 defaultReaderClosedPromiseInitialize(reader);
324 defaultReaderClosedPromiseResolve(reader);
325}
326function defaultReaderClosedPromiseReject(reader, reason) {
327 setPromiseIsHandledToTrue(reader._closedPromise);
328 reader._closedPromise_reject(reason);
329 reader._closedPromise_resolve = undefined;
330 reader._closedPromise_reject = undefined;
331}
332function defaultReaderClosedPromiseResetToRejected(reader, reason) {
333 defaultReaderClosedPromiseInitializeAsRejected(reader, reason);
334}
335function defaultReaderClosedPromiseResolve(reader) {
336 reader._closedPromise_resolve(undefined);
337 reader._closedPromise_resolve = undefined;
338 reader._closedPromise_reject = undefined;
339}
340
341const CancelSteps = SymbolPolyfill('[[CancelSteps]]');
342const PullSteps = SymbolPolyfill('[[PullSteps]]');
343
344// Abstract operations for the ReadableStream.
345function AcquireReadableStreamDefaultReader(stream, forAuthorCode = false) {
346 const reader = new ReadableStreamDefaultReader(stream);
347 reader._forAuthorCode = forAuthorCode;
348 return reader;
349}
350// ReadableStream API exposed for controllers.
351function ReadableStreamAddReadRequest(stream) {
352 const promise = newPromise((resolve, reject) => {
353 const readRequest = {
354 _resolve: resolve,
355 _reject: reject
356 };
357 stream._reader._readRequests.push(readRequest);
358 });
359 return promise;
360}
361function ReadableStreamFulfillReadRequest(stream, chunk, done) {
362 const reader = stream._reader;
363 const readRequest = reader._readRequests.shift();
364 readRequest._resolve(ReadableStreamCreateReadResult(chunk, done, reader._forAuthorCode));
365}
366function ReadableStreamGetNumReadRequests(stream) {
367 return stream._reader._readRequests.length;
368}
369function ReadableStreamHasDefaultReader(stream) {
370 const reader = stream._reader;
371 if (reader === undefined) {
372 return false;
373 }
374 if (!IsReadableStreamDefaultReader(reader)) {
375 return false;
376 }
377 return true;
378}
379class ReadableStreamDefaultReader {
380 constructor(stream) {
381 if (IsReadableStream(stream) === false) {
382 throw new TypeError('ReadableStreamDefaultReader can only be constructed with a ReadableStream instance');
383 }
384 if (IsReadableStreamLocked(stream) === true) {
385 throw new TypeError('This stream has already been locked for exclusive reading by another reader');
386 }
387 ReadableStreamReaderGenericInitialize(this, stream);
388 this._readRequests = new SimpleQueue();
389 }
390 get closed() {
391 if (!IsReadableStreamDefaultReader(this)) {
392 return promiseRejectedWith(defaultReaderBrandCheckException('closed'));
393 }
394 return this._closedPromise;
395 }
396 cancel(reason) {
397 if (!IsReadableStreamDefaultReader(this)) {
398 return promiseRejectedWith(defaultReaderBrandCheckException('cancel'));
399 }
400 if (this._ownerReadableStream === undefined) {
401 return promiseRejectedWith(readerLockException('cancel'));
402 }
403 return ReadableStreamReaderGenericCancel(this, reason);
404 }
405 read() {
406 if (!IsReadableStreamDefaultReader(this)) {
407 return promiseRejectedWith(defaultReaderBrandCheckException('read'));
408 }
409 if (this._ownerReadableStream === undefined) {
410 return promiseRejectedWith(readerLockException('read from'));
411 }
412 return ReadableStreamDefaultReaderRead(this);
413 }
414 releaseLock() {
415 if (!IsReadableStreamDefaultReader(this)) {
416 throw defaultReaderBrandCheckException('releaseLock');
417 }
418 if (this._ownerReadableStream === undefined) {
419 return;
420 }
421 if (this._readRequests.length > 0) {
422 throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
423 }
424 ReadableStreamReaderGenericRelease(this);
425 }
426}
427// Abstract operations for the readers.
428function IsReadableStreamDefaultReader(x) {
429 if (!typeIsObject(x)) {
430 return false;
431 }
432 if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) {
433 return false;
434 }
435 return true;
436}
437function ReadableStreamDefaultReaderRead(reader) {
438 const stream = reader._ownerReadableStream;
439 stream._disturbed = true;
440 if (stream._state === 'closed') {
441 return promiseResolvedWith(ReadableStreamCreateReadResult(undefined, true, reader._forAuthorCode));
442 }
443 if (stream._state === 'errored') {
444 return promiseRejectedWith(stream._storedError);
445 }
446 return stream._readableStreamController[PullSteps]();
447}
448// Helper functions for the ReadableStreamDefaultReader.
449function defaultReaderBrandCheckException(name) {
450 return new TypeError(`ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`);
451}
452
453/// <reference lib="es2018.asynciterable" />
454let AsyncIteratorPrototype;
455if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
456 // We're running inside a ES2018+ environment, but we're compiling to an older syntax.
457 // We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.
458 AsyncIteratorPrototype = {
459 // 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )
460 // https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator
461 [SymbolPolyfill.asyncIterator]() {
462 return this;
463 }
464 };
465 Object.defineProperty(AsyncIteratorPrototype, SymbolPolyfill.asyncIterator, { enumerable: false });
466}
467
468/// <reference lib="es2018.asynciterable" />
469const ReadableStreamAsyncIteratorPrototype = {
470 next() {
471 if (IsReadableStreamAsyncIterator(this) === false) {
472 return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));
473 }
474 const reader = this._asyncIteratorReader;
475 if (reader._ownerReadableStream === undefined) {
476 return promiseRejectedWith(readerLockException('iterate'));
477 }
478 return transformPromiseWith(ReadableStreamDefaultReaderRead(reader), result => {
479 const done = result.done;
480 if (done) {
481 ReadableStreamReaderGenericRelease(reader);
482 }
483 const value = result.value;
484 return ReadableStreamCreateReadResult(value, done, true);
485 });
486 },
487 return(value) {
488 if (IsReadableStreamAsyncIterator(this) === false) {
489 return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));
490 }
491 const reader = this._asyncIteratorReader;
492 if (reader._ownerReadableStream === undefined) {
493 return promiseRejectedWith(readerLockException('finish iterating'));
494 }
495 if (reader._readRequests.length > 0) {
496 return promiseRejectedWith(new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled'));
497 }
498 if (this._preventCancel === false) {
499 const result = ReadableStreamReaderGenericCancel(reader, value);
500 ReadableStreamReaderGenericRelease(reader);
501 return transformPromiseWith(result, () => ReadableStreamCreateReadResult(value, true, true));
502 }
503 ReadableStreamReaderGenericRelease(reader);
504 return promiseResolvedWith(ReadableStreamCreateReadResult(value, true, true));
505 }
506};
507if (AsyncIteratorPrototype !== undefined) {
508 Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);
509}
510Object.defineProperty(ReadableStreamAsyncIteratorPrototype, 'next', { enumerable: false });
511Object.defineProperty(ReadableStreamAsyncIteratorPrototype, 'return', { enumerable: false });
512// Abstract operations for the ReadableStream.
513function AcquireReadableStreamAsyncIterator(stream, preventCancel = false) {
514 const reader = AcquireReadableStreamDefaultReader(stream);
515 const iterator = Object.create(ReadableStreamAsyncIteratorPrototype);
516 iterator._asyncIteratorReader = reader;
517 iterator._preventCancel = Boolean(preventCancel);
518 return iterator;
519}
520function IsReadableStreamAsyncIterator(x) {
521 if (!typeIsObject(x)) {
522 return false;
523 }
524 if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorReader')) {
525 return false;
526 }
527 return true;
528}
529// Helper functions for the ReadableStream.
530function streamAsyncIteratorBrandCheckException(name) {
531 return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`);
532}
533
534function DequeueValue(container) {
535 const pair = container._queue.shift();
536 container._queueTotalSize -= pair.size;
537 if (container._queueTotalSize < 0) {
538 container._queueTotalSize = 0;
539 }
540 return pair.value;
541}
542function EnqueueValueWithSize(container, value, size) {
543 size = Number(size);
544 if (!IsFiniteNonNegativeNumber(size)) {
545 throw new RangeError('Size must be a finite, non-NaN, non-negative number.');
546 }
547 container._queue.push({ value, size });
548 container._queueTotalSize += size;
549}
550function PeekQueueValue(container) {
551 const pair = container._queue.peek();
552 return pair.value;
553}
554function ResetQueue(container) {
555 container._queue = new SimpleQueue();
556 container._queueTotalSize = 0;
557}
558
559const AbortSteps = SymbolPolyfill('[[AbortSteps]]');
560const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]');
561class WritableStream {
562 constructor(underlyingSink = {}, strategy = {}) {
563 InitializeWritableStream(this);
564 const size = strategy.size;
565 let highWaterMark = strategy.highWaterMark;
566 const type = underlyingSink.type;
567 if (type !== undefined) {
568 throw new RangeError('Invalid type is specified');
569 }
570 const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size);
571 if (highWaterMark === undefined) {
572 highWaterMark = 1;
573 }
574 highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark);
575 SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm);
576 }
577 get locked() {
578 if (IsWritableStream(this) === false) {
579 throw streamBrandCheckException('locked');
580 }
581 return IsWritableStreamLocked(this);
582 }
583 abort(reason) {
584 if (IsWritableStream(this) === false) {
585 return promiseRejectedWith(streamBrandCheckException('abort'));
586 }
587 if (IsWritableStreamLocked(this) === true) {
588 return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer'));
589 }
590 return WritableStreamAbort(this, reason);
591 }
592 close() {
593 if (IsWritableStream(this) === false) {
594 return promiseRejectedWith(streamBrandCheckException('close'));
595 }
596 if (IsWritableStreamLocked(this) === true) {
597 return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer'));
598 }
599 if (WritableStreamCloseQueuedOrInFlight(this) === true) {
600 return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
601 }
602 return WritableStreamClose(this);
603 }
604 getWriter() {
605 if (IsWritableStream(this) === false) {
606 throw streamBrandCheckException('getWriter');
607 }
608 return AcquireWritableStreamDefaultWriter(this);
609 }
610}
611// Abstract operations for the WritableStream.
612function AcquireWritableStreamDefaultWriter(stream) {
613 return new WritableStreamDefaultWriter(stream);
614}
615// Throws if and only if startAlgorithm throws.
616function CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
617 const stream = Object.create(WritableStream.prototype);
618 InitializeWritableStream(stream);
619 const controller = Object.create(WritableStreamDefaultController.prototype);
620 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
621 return stream;
622}
623function InitializeWritableStream(stream) {
624 stream._state = 'writable';
625 // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is
626 // 'erroring' or 'errored'. May be set to an undefined value.
627 stream._storedError = undefined;
628 stream._writer = undefined;
629 // Initialize to undefined first because the constructor of the controller checks this
630 // variable to validate the caller.
631 stream._writableStreamController = undefined;
632 // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data
633 // producer without waiting for the queued writes to finish.
634 stream._writeRequests = new SimpleQueue();
635 // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents
636 // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here.
637 stream._inFlightWriteRequest = undefined;
638 // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer
639 // has been detached.
640 stream._closeRequest = undefined;
641 // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it
642 // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here.
643 stream._inFlightCloseRequest = undefined;
644 // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached.
645 stream._pendingAbortRequest = undefined;
646 // The backpressure signal set by the controller.
647 stream._backpressure = false;
648}
649function IsWritableStream(x) {
650 if (!typeIsObject(x)) {
651 return false;
652 }
653 if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) {
654 return false;
655 }
656 return true;
657}
658function IsWritableStreamLocked(stream) {
659 if (stream._writer === undefined) {
660 return false;
661 }
662 return true;
663}
664function WritableStreamAbort(stream, reason) {
665 const state = stream._state;
666 if (state === 'closed' || state === 'errored') {
667 return promiseResolvedWith(undefined);
668 }
669 if (stream._pendingAbortRequest !== undefined) {
670 return stream._pendingAbortRequest._promise;
671 }
672 let wasAlreadyErroring = false;
673 if (state === 'erroring') {
674 wasAlreadyErroring = true;
675 // reason will not be used, so don't keep a reference to it.
676 reason = undefined;
677 }
678 const promise = newPromise((resolve, reject) => {
679 stream._pendingAbortRequest = {
680 _promise: undefined,
681 _resolve: resolve,
682 _reject: reject,
683 _reason: reason,
684 _wasAlreadyErroring: wasAlreadyErroring
685 };
686 });
687 stream._pendingAbortRequest._promise = promise;
688 if (wasAlreadyErroring === false) {
689 WritableStreamStartErroring(stream, reason);
690 }
691 return promise;
692}
693function WritableStreamClose(stream) {
694 const state = stream._state;
695 if (state === 'closed' || state === 'errored') {
696 return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`));
697 }
698 const promise = newPromise((resolve, reject) => {
699 const closeRequest = {
700 _resolve: resolve,
701 _reject: reject
702 };
703 stream._closeRequest = closeRequest;
704 });
705 const writer = stream._writer;
706 if (writer !== undefined && stream._backpressure === true && state === 'writable') {
707 defaultWriterReadyPromiseResolve(writer);
708 }
709 WritableStreamDefaultControllerClose(stream._writableStreamController);
710 return promise;
711}
712// WritableStream API exposed for controllers.
713function WritableStreamAddWriteRequest(stream) {
714 const promise = newPromise((resolve, reject) => {
715 const writeRequest = {
716 _resolve: resolve,
717 _reject: reject
718 };
719 stream._writeRequests.push(writeRequest);
720 });
721 return promise;
722}
723function WritableStreamDealWithRejection(stream, error) {
724 const state = stream._state;
725 if (state === 'writable') {
726 WritableStreamStartErroring(stream, error);
727 return;
728 }
729 WritableStreamFinishErroring(stream);
730}
731function WritableStreamStartErroring(stream, reason) {
732 const controller = stream._writableStreamController;
733 stream._state = 'erroring';
734 stream._storedError = reason;
735 const writer = stream._writer;
736 if (writer !== undefined) {
737 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);
738 }
739 if (WritableStreamHasOperationMarkedInFlight(stream) === false && controller._started === true) {
740 WritableStreamFinishErroring(stream);
741 }
742}
743function WritableStreamFinishErroring(stream) {
744 stream._state = 'errored';
745 stream._writableStreamController[ErrorSteps]();
746 const storedError = stream._storedError;
747 stream._writeRequests.forEach(writeRequest => {
748 writeRequest._reject(storedError);
749 });
750 stream._writeRequests = new SimpleQueue();
751 if (stream._pendingAbortRequest === undefined) {
752 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
753 return;
754 }
755 const abortRequest = stream._pendingAbortRequest;
756 stream._pendingAbortRequest = undefined;
757 if (abortRequest._wasAlreadyErroring === true) {
758 abortRequest._reject(storedError);
759 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
760 return;
761 }
762 const promise = stream._writableStreamController[AbortSteps](abortRequest._reason);
763 uponPromise(promise, () => {
764 abortRequest._resolve();
765 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
766 }, (reason) => {
767 abortRequest._reject(reason);
768 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
769 });
770}
771function WritableStreamFinishInFlightWrite(stream) {
772 stream._inFlightWriteRequest._resolve(undefined);
773 stream._inFlightWriteRequest = undefined;
774}
775function WritableStreamFinishInFlightWriteWithError(stream, error) {
776 stream._inFlightWriteRequest._reject(error);
777 stream._inFlightWriteRequest = undefined;
778 WritableStreamDealWithRejection(stream, error);
779}
780function WritableStreamFinishInFlightClose(stream) {
781 stream._inFlightCloseRequest._resolve(undefined);
782 stream._inFlightCloseRequest = undefined;
783 const state = stream._state;
784 if (state === 'erroring') {
785 // The error was too late to do anything, so it is ignored.
786 stream._storedError = undefined;
787 if (stream._pendingAbortRequest !== undefined) {
788 stream._pendingAbortRequest._resolve();
789 stream._pendingAbortRequest = undefined;
790 }
791 }
792 stream._state = 'closed';
793 const writer = stream._writer;
794 if (writer !== undefined) {
795 defaultWriterClosedPromiseResolve(writer);
796 }
797}
798function WritableStreamFinishInFlightCloseWithError(stream, error) {
799 stream._inFlightCloseRequest._reject(error);
800 stream._inFlightCloseRequest = undefined;
801 // Never execute sink abort() after sink close().
802 if (stream._pendingAbortRequest !== undefined) {
803 stream._pendingAbortRequest._reject(error);
804 stream._pendingAbortRequest = undefined;
805 }
806 WritableStreamDealWithRejection(stream, error);
807}
808// TODO(ricea): Fix alphabetical order.
809function WritableStreamCloseQueuedOrInFlight(stream) {
810 if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) {
811 return false;
812 }
813 return true;
814}
815function WritableStreamHasOperationMarkedInFlight(stream) {
816 if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) {
817 return false;
818 }
819 return true;
820}
821function WritableStreamMarkCloseRequestInFlight(stream) {
822 stream._inFlightCloseRequest = stream._closeRequest;
823 stream._closeRequest = undefined;
824}
825function WritableStreamMarkFirstWriteRequestInFlight(stream) {
826 stream._inFlightWriteRequest = stream._writeRequests.shift();
827}
828function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) {
829 if (stream._closeRequest !== undefined) {
830 stream._closeRequest._reject(stream._storedError);
831 stream._closeRequest = undefined;
832 }
833 const writer = stream._writer;
834 if (writer !== undefined) {
835 defaultWriterClosedPromiseReject(writer, stream._storedError);
836 }
837}
838function WritableStreamUpdateBackpressure(stream, backpressure) {
839 const writer = stream._writer;
840 if (writer !== undefined && backpressure !== stream._backpressure) {
841 if (backpressure === true) {
842 defaultWriterReadyPromiseReset(writer);
843 }
844 else {
845 defaultWriterReadyPromiseResolve(writer);
846 }
847 }
848 stream._backpressure = backpressure;
849}
850class WritableStreamDefaultWriter {
851 constructor(stream) {
852 if (IsWritableStream(stream) === false) {
853 throw new TypeError('WritableStreamDefaultWriter can only be constructed with a WritableStream instance');
854 }
855 if (IsWritableStreamLocked(stream) === true) {
856 throw new TypeError('This stream has already been locked for exclusive writing by another writer');
857 }
858 this._ownerWritableStream = stream;
859 stream._writer = this;
860 const state = stream._state;
861 if (state === 'writable') {
862 if (WritableStreamCloseQueuedOrInFlight(stream) === false && stream._backpressure === true) {
863 defaultWriterReadyPromiseInitialize(this);
864 }
865 else {
866 defaultWriterReadyPromiseInitializeAsResolved(this);
867 }
868 defaultWriterClosedPromiseInitialize(this);
869 }
870 else if (state === 'erroring') {
871 defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError);
872 defaultWriterClosedPromiseInitialize(this);
873 }
874 else if (state === 'closed') {
875 defaultWriterReadyPromiseInitializeAsResolved(this);
876 defaultWriterClosedPromiseInitializeAsResolved(this);
877 }
878 else {
879 const storedError = stream._storedError;
880 defaultWriterReadyPromiseInitializeAsRejected(this, storedError);
881 defaultWriterClosedPromiseInitializeAsRejected(this, storedError);
882 }
883 }
884 get closed() {
885 if (IsWritableStreamDefaultWriter(this) === false) {
886 return promiseRejectedWith(defaultWriterBrandCheckException('closed'));
887 }
888 return this._closedPromise;
889 }
890 get desiredSize() {
891 if (IsWritableStreamDefaultWriter(this) === false) {
892 throw defaultWriterBrandCheckException('desiredSize');
893 }
894 if (this._ownerWritableStream === undefined) {
895 throw defaultWriterLockException('desiredSize');
896 }
897 return WritableStreamDefaultWriterGetDesiredSize(this);
898 }
899 get ready() {
900 if (IsWritableStreamDefaultWriter(this) === false) {
901 return promiseRejectedWith(defaultWriterBrandCheckException('ready'));
902 }
903 return this._readyPromise;
904 }
905 abort(reason) {
906 if (IsWritableStreamDefaultWriter(this) === false) {
907 return promiseRejectedWith(defaultWriterBrandCheckException('abort'));
908 }
909 if (this._ownerWritableStream === undefined) {
910 return promiseRejectedWith(defaultWriterLockException('abort'));
911 }
912 return WritableStreamDefaultWriterAbort(this, reason);
913 }
914 close() {
915 if (IsWritableStreamDefaultWriter(this) === false) {
916 return promiseRejectedWith(defaultWriterBrandCheckException('close'));
917 }
918 const stream = this._ownerWritableStream;
919 if (stream === undefined) {
920 return promiseRejectedWith(defaultWriterLockException('close'));
921 }
922 if (WritableStreamCloseQueuedOrInFlight(stream) === true) {
923 return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
924 }
925 return WritableStreamDefaultWriterClose(this);
926 }
927 releaseLock() {
928 if (IsWritableStreamDefaultWriter(this) === false) {
929 throw defaultWriterBrandCheckException('releaseLock');
930 }
931 const stream = this._ownerWritableStream;
932 if (stream === undefined) {
933 return;
934 }
935 WritableStreamDefaultWriterRelease(this);
936 }
937 write(chunk) {
938 if (IsWritableStreamDefaultWriter(this) === false) {
939 return promiseRejectedWith(defaultWriterBrandCheckException('write'));
940 }
941 if (this._ownerWritableStream === undefined) {
942 return promiseRejectedWith(defaultWriterLockException('write to'));
943 }
944 return WritableStreamDefaultWriterWrite(this, chunk);
945 }
946}
947// Abstract operations for the WritableStreamDefaultWriter.
948function IsWritableStreamDefaultWriter(x) {
949 if (!typeIsObject(x)) {
950 return false;
951 }
952 if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) {
953 return false;
954 }
955 return true;
956}
957// A client of WritableStreamDefaultWriter may use these functions directly to bypass state check.
958function WritableStreamDefaultWriterAbort(writer, reason) {
959 const stream = writer._ownerWritableStream;
960 return WritableStreamAbort(stream, reason);
961}
962function WritableStreamDefaultWriterClose(writer) {
963 const stream = writer._ownerWritableStream;
964 return WritableStreamClose(stream);
965}
966function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) {
967 const stream = writer._ownerWritableStream;
968 const state = stream._state;
969 if (WritableStreamCloseQueuedOrInFlight(stream) === true || state === 'closed') {
970 return promiseResolvedWith(undefined);
971 }
972 if (state === 'errored') {
973 return promiseRejectedWith(stream._storedError);
974 }
975 return WritableStreamDefaultWriterClose(writer);
976}
977function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) {
978 if (writer._closedPromiseState === 'pending') {
979 defaultWriterClosedPromiseReject(writer, error);
980 }
981 else {
982 defaultWriterClosedPromiseResetToRejected(writer, error);
983 }
984}
985function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) {
986 if (writer._readyPromiseState === 'pending') {
987 defaultWriterReadyPromiseReject(writer, error);
988 }
989 else {
990 defaultWriterReadyPromiseResetToRejected(writer, error);
991 }
992}
993function WritableStreamDefaultWriterGetDesiredSize(writer) {
994 const stream = writer._ownerWritableStream;
995 const state = stream._state;
996 if (state === 'errored' || state === 'erroring') {
997 return null;
998 }
999 if (state === 'closed') {
1000 return 0;
1001 }
1002 return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController);
1003}
1004function WritableStreamDefaultWriterRelease(writer) {
1005 const stream = writer._ownerWritableStream;
1006 const releasedError = new TypeError('Writer was released and can no longer be used to monitor the stream\'s closedness');
1007 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
1008 // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not
1009 // rejected until afterwards. This means that simply testing state will not work.
1010 WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
1011 stream._writer = undefined;
1012 writer._ownerWritableStream = undefined;
1013}
1014function WritableStreamDefaultWriterWrite(writer, chunk) {
1015 const stream = writer._ownerWritableStream;
1016 const controller = stream._writableStreamController;
1017 const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk);
1018 if (stream !== writer._ownerWritableStream) {
1019 return promiseRejectedWith(defaultWriterLockException('write to'));
1020 }
1021 const state = stream._state;
1022 if (state === 'errored') {
1023 return promiseRejectedWith(stream._storedError);
1024 }
1025 if (WritableStreamCloseQueuedOrInFlight(stream) === true || state === 'closed') {
1026 return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to'));
1027 }
1028 if (state === 'erroring') {
1029 return promiseRejectedWith(stream._storedError);
1030 }
1031 const promise = WritableStreamAddWriteRequest(stream);
1032 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize);
1033 return promise;
1034}
1035class WritableStreamDefaultController {
1036 /** @internal */
1037 constructor() {
1038 throw new TypeError('WritableStreamDefaultController cannot be constructed explicitly');
1039 }
1040 error(e) {
1041 if (IsWritableStreamDefaultController(this) === false) {
1042 throw new TypeError('WritableStreamDefaultController.prototype.error can only be used on a WritableStreamDefaultController');
1043 }
1044 const state = this._controlledWritableStream._state;
1045 if (state !== 'writable') {
1046 // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so
1047 // just treat it as a no-op.
1048 return;
1049 }
1050 WritableStreamDefaultControllerError(this, e);
1051 }
1052 /** @internal */
1053 [AbortSteps](reason) {
1054 const result = this._abortAlgorithm(reason);
1055 WritableStreamDefaultControllerClearAlgorithms(this);
1056 return result;
1057 }
1058 /** @internal */
1059 [ErrorSteps]() {
1060 ResetQueue(this);
1061 }
1062}
1063// Abstract operations implementing interface required by the WritableStream.
1064function IsWritableStreamDefaultController(x) {
1065 if (!typeIsObject(x)) {
1066 return false;
1067 }
1068 if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) {
1069 return false;
1070 }
1071 return true;
1072}
1073function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) {
1074 controller._controlledWritableStream = stream;
1075 stream._writableStreamController = controller;
1076 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
1077 controller._queue = undefined;
1078 controller._queueTotalSize = undefined;
1079 ResetQueue(controller);
1080 controller._started = false;
1081 controller._strategySizeAlgorithm = sizeAlgorithm;
1082 controller._strategyHWM = highWaterMark;
1083 controller._writeAlgorithm = writeAlgorithm;
1084 controller._closeAlgorithm = closeAlgorithm;
1085 controller._abortAlgorithm = abortAlgorithm;
1086 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
1087 WritableStreamUpdateBackpressure(stream, backpressure);
1088 const startResult = startAlgorithm();
1089 const startPromise = promiseResolvedWith(startResult);
1090 uponPromise(startPromise, () => {
1091 controller._started = true;
1092 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
1093 }, r => {
1094 controller._started = true;
1095 WritableStreamDealWithRejection(stream, r);
1096 });
1097}
1098function SetUpWritableStreamDefaultControllerFromUnderlyingSink(stream, underlyingSink, highWaterMark, sizeAlgorithm) {
1099 const controller = Object.create(WritableStreamDefaultController.prototype);
1100 function startAlgorithm() {
1101 return InvokeOrNoop(underlyingSink, 'start', [controller]);
1102 }
1103 const writeAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingSink, 'write', 1, [controller]);
1104 const closeAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingSink, 'close', 0, []);
1105 const abortAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingSink, 'abort', 1, []);
1106 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
1107}
1108// ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls.
1109function WritableStreamDefaultControllerClearAlgorithms(controller) {
1110 controller._writeAlgorithm = undefined;
1111 controller._closeAlgorithm = undefined;
1112 controller._abortAlgorithm = undefined;
1113 controller._strategySizeAlgorithm = undefined;
1114}
1115function WritableStreamDefaultControllerClose(controller) {
1116 EnqueueValueWithSize(controller, 'close', 0);
1117 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
1118}
1119function WritableStreamDefaultControllerGetChunkSize(controller, chunk) {
1120 try {
1121 return controller._strategySizeAlgorithm(chunk);
1122 }
1123 catch (chunkSizeE) {
1124 WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE);
1125 return 1;
1126 }
1127}
1128function WritableStreamDefaultControllerGetDesiredSize(controller) {
1129 return controller._strategyHWM - controller._queueTotalSize;
1130}
1131function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) {
1132 const writeRecord = { chunk };
1133 try {
1134 EnqueueValueWithSize(controller, writeRecord, chunkSize);
1135 }
1136 catch (enqueueE) {
1137 WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE);
1138 return;
1139 }
1140 const stream = controller._controlledWritableStream;
1141 if (WritableStreamCloseQueuedOrInFlight(stream) === false && stream._state === 'writable') {
1142 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
1143 WritableStreamUpdateBackpressure(stream, backpressure);
1144 }
1145 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
1146}
1147// Abstract operations for the WritableStreamDefaultController.
1148function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) {
1149 const stream = controller._controlledWritableStream;
1150 if (controller._started === false) {
1151 return;
1152 }
1153 if (stream._inFlightWriteRequest !== undefined) {
1154 return;
1155 }
1156 const state = stream._state;
1157 if (state === 'erroring') {
1158 WritableStreamFinishErroring(stream);
1159 return;
1160 }
1161 if (controller._queue.length === 0) {
1162 return;
1163 }
1164 const writeRecord = PeekQueueValue(controller);
1165 if (writeRecord === 'close') {
1166 WritableStreamDefaultControllerProcessClose(controller);
1167 }
1168 else {
1169 WritableStreamDefaultControllerProcessWrite(controller, writeRecord.chunk);
1170 }
1171}
1172function WritableStreamDefaultControllerErrorIfNeeded(controller, error) {
1173 if (controller._controlledWritableStream._state === 'writable') {
1174 WritableStreamDefaultControllerError(controller, error);
1175 }
1176}
1177function WritableStreamDefaultControllerProcessClose(controller) {
1178 const stream = controller._controlledWritableStream;
1179 WritableStreamMarkCloseRequestInFlight(stream);
1180 DequeueValue(controller);
1181 const sinkClosePromise = controller._closeAlgorithm();
1182 WritableStreamDefaultControllerClearAlgorithms(controller);
1183 uponPromise(sinkClosePromise, () => {
1184 WritableStreamFinishInFlightClose(stream);
1185 }, reason => {
1186 WritableStreamFinishInFlightCloseWithError(stream, reason);
1187 });
1188}
1189function WritableStreamDefaultControllerProcessWrite(controller, chunk) {
1190 const stream = controller._controlledWritableStream;
1191 WritableStreamMarkFirstWriteRequestInFlight(stream);
1192 const sinkWritePromise = controller._writeAlgorithm(chunk);
1193 uponPromise(sinkWritePromise, () => {
1194 WritableStreamFinishInFlightWrite(stream);
1195 const state = stream._state;
1196 DequeueValue(controller);
1197 if (WritableStreamCloseQueuedOrInFlight(stream) === false && state === 'writable') {
1198 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
1199 WritableStreamUpdateBackpressure(stream, backpressure);
1200 }
1201 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
1202 }, reason => {
1203 if (stream._state === 'writable') {
1204 WritableStreamDefaultControllerClearAlgorithms(controller);
1205 }
1206 WritableStreamFinishInFlightWriteWithError(stream, reason);
1207 });
1208}
1209function WritableStreamDefaultControllerGetBackpressure(controller) {
1210 const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller);
1211 return desiredSize <= 0;
1212}
1213// A client of WritableStreamDefaultController may use these functions directly to bypass state check.
1214function WritableStreamDefaultControllerError(controller, error) {
1215 const stream = controller._controlledWritableStream;
1216 WritableStreamDefaultControllerClearAlgorithms(controller);
1217 WritableStreamStartErroring(stream, error);
1218}
1219// Helper functions for the WritableStream.
1220function streamBrandCheckException(name) {
1221 return new TypeError(`WritableStream.prototype.${name} can only be used on a WritableStream`);
1222}
1223// Helper functions for the WritableStreamDefaultWriter.
1224function defaultWriterBrandCheckException(name) {
1225 return new TypeError(`WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter`);
1226}
1227function defaultWriterLockException(name) {
1228 return new TypeError('Cannot ' + name + ' a stream using a released writer');
1229}
1230function defaultWriterClosedPromiseInitialize(writer) {
1231 writer._closedPromise = newPromise((resolve, reject) => {
1232 writer._closedPromise_resolve = resolve;
1233 writer._closedPromise_reject = reject;
1234 writer._closedPromiseState = 'pending';
1235 });
1236}
1237function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) {
1238 defaultWriterClosedPromiseInitialize(writer);
1239 defaultWriterClosedPromiseReject(writer, reason);
1240}
1241function defaultWriterClosedPromiseInitializeAsResolved(writer) {
1242 defaultWriterClosedPromiseInitialize(writer);
1243 defaultWriterClosedPromiseResolve(writer);
1244}
1245function defaultWriterClosedPromiseReject(writer, reason) {
1246 setPromiseIsHandledToTrue(writer._closedPromise);
1247 writer._closedPromise_reject(reason);
1248 writer._closedPromise_resolve = undefined;
1249 writer._closedPromise_reject = undefined;
1250 writer._closedPromiseState = 'rejected';
1251}
1252function defaultWriterClosedPromiseResetToRejected(writer, reason) {
1253 defaultWriterClosedPromiseInitializeAsRejected(writer, reason);
1254}
1255function defaultWriterClosedPromiseResolve(writer) {
1256 writer._closedPromise_resolve(undefined);
1257 writer._closedPromise_resolve = undefined;
1258 writer._closedPromise_reject = undefined;
1259 writer._closedPromiseState = 'resolved';
1260}
1261function defaultWriterReadyPromiseInitialize(writer) {
1262 writer._readyPromise = newPromise((resolve, reject) => {
1263 writer._readyPromise_resolve = resolve;
1264 writer._readyPromise_reject = reject;
1265 });
1266 writer._readyPromiseState = 'pending';
1267}
1268function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) {
1269 defaultWriterReadyPromiseInitialize(writer);
1270 defaultWriterReadyPromiseReject(writer, reason);
1271}
1272function defaultWriterReadyPromiseInitializeAsResolved(writer) {
1273 defaultWriterReadyPromiseInitialize(writer);
1274 defaultWriterReadyPromiseResolve(writer);
1275}
1276function defaultWriterReadyPromiseReject(writer, reason) {
1277 setPromiseIsHandledToTrue(writer._readyPromise);
1278 writer._readyPromise_reject(reason);
1279 writer._readyPromise_resolve = undefined;
1280 writer._readyPromise_reject = undefined;
1281 writer._readyPromiseState = 'rejected';
1282}
1283function defaultWriterReadyPromiseReset(writer) {
1284 defaultWriterReadyPromiseInitialize(writer);
1285}
1286function defaultWriterReadyPromiseResetToRejected(writer, reason) {
1287 defaultWriterReadyPromiseInitializeAsRejected(writer, reason);
1288}
1289function defaultWriterReadyPromiseResolve(writer) {
1290 writer._readyPromise_resolve(undefined);
1291 writer._readyPromise_resolve = undefined;
1292 writer._readyPromise_reject = undefined;
1293 writer._readyPromiseState = 'fulfilled';
1294}
1295
1296function isAbortSignal(value) {
1297 if (typeof value !== 'object' || value === null) {
1298 return false;
1299 }
1300 try {
1301 return typeof value.aborted === 'boolean';
1302 }
1303 catch (_a) {
1304 // AbortSignal.prototype.aborted throws if its brand check fails
1305 return false;
1306 }
1307}
1308
1309/// <reference lib="dom" />
1310const NativeDOMException = typeof DOMException !== 'undefined' ? DOMException : undefined;
1311
1312/// <reference types="node" />
1313function isDOMExceptionConstructor(ctor) {
1314 if (!(typeof ctor === 'function' || typeof ctor === 'object')) {
1315 return false;
1316 }
1317 try {
1318 new ctor();
1319 return true;
1320 }
1321 catch (_a) {
1322 return false;
1323 }
1324}
1325function createDOMExceptionPolyfill() {
1326 const ctor = function DOMException(message, name) {
1327 this.message = message || '';
1328 this.name = name || 'Error';
1329 if (Error.captureStackTrace) {
1330 Error.captureStackTrace(this, this.constructor);
1331 }
1332 };
1333 ctor.prototype = Object.create(Error.prototype);
1334 Object.defineProperty(ctor.prototype, 'constructor', { value: ctor, writable: true, configurable: true });
1335 return ctor;
1336}
1337const DOMException$1 = isDOMExceptionConstructor(NativeDOMException) ? NativeDOMException : createDOMExceptionPolyfill();
1338
1339function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventCancel, signal) {
1340 const reader = AcquireReadableStreamDefaultReader(source);
1341 const writer = AcquireWritableStreamDefaultWriter(dest);
1342 source._disturbed = true;
1343 let shuttingDown = false;
1344 // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown.
1345 let currentWrite = promiseResolvedWith(undefined);
1346 return newPromise((resolve, reject) => {
1347 let abortAlgorithm;
1348 if (signal !== undefined) {
1349 abortAlgorithm = () => {
1350 const error = new DOMException$1('Aborted', 'AbortError');
1351 const actions = [];
1352 if (preventAbort === false) {
1353 actions.push(() => {
1354 if (dest._state === 'writable') {
1355 return WritableStreamAbort(dest, error);
1356 }
1357 return promiseResolvedWith(undefined);
1358 });
1359 }
1360 if (preventCancel === false) {
1361 actions.push(() => {
1362 if (source._state === 'readable') {
1363 return ReadableStreamCancel(source, error);
1364 }
1365 return promiseResolvedWith(undefined);
1366 });
1367 }
1368 shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error);
1369 };
1370 if (signal.aborted === true) {
1371 abortAlgorithm();
1372 return;
1373 }
1374 signal.addEventListener('abort', abortAlgorithm);
1375 }
1376 // Using reader and writer, read all chunks from this and write them to dest
1377 // - Backpressure must be enforced
1378 // - Shutdown must stop all activity
1379 function pipeLoop() {
1380 return newPromise((resolveLoop, rejectLoop) => {
1381 function next(done) {
1382 if (done) {
1383 resolveLoop();
1384 }
1385 else {
1386 // Use `PerformPromiseThen` instead of `uponPromise` to avoid
1387 // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers
1388 PerformPromiseThen(pipeStep(), next, rejectLoop);
1389 }
1390 }
1391 next(false);
1392 });
1393 }
1394 function pipeStep() {
1395 if (shuttingDown === true) {
1396 return promiseResolvedWith(true);
1397 }
1398 return PerformPromiseThen(writer._readyPromise, () => {
1399 return PerformPromiseThen(ReadableStreamDefaultReaderRead(reader), result => {
1400 if (result.done === true) {
1401 return true;
1402 }
1403 currentWrite = PerformPromiseThen(WritableStreamDefaultWriterWrite(writer, result.value), undefined, noop);
1404 return false;
1405 });
1406 });
1407 }
1408 // Errors must be propagated forward
1409 isOrBecomesErrored(source, reader._closedPromise, storedError => {
1410 if (preventAbort === false) {
1411 shutdownWithAction(() => WritableStreamAbort(dest, storedError), true, storedError);
1412 }
1413 else {
1414 shutdown(true, storedError);
1415 }
1416 });
1417 // Errors must be propagated backward
1418 isOrBecomesErrored(dest, writer._closedPromise, storedError => {
1419 if (preventCancel === false) {
1420 shutdownWithAction(() => ReadableStreamCancel(source, storedError), true, storedError);
1421 }
1422 else {
1423 shutdown(true, storedError);
1424 }
1425 });
1426 // Closing must be propagated forward
1427 isOrBecomesClosed(source, reader._closedPromise, () => {
1428 if (preventClose === false) {
1429 shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer));
1430 }
1431 else {
1432 shutdown();
1433 }
1434 });
1435 // Closing must be propagated backward
1436 if (WritableStreamCloseQueuedOrInFlight(dest) === true || dest._state === 'closed') {
1437 const destClosed = new TypeError('the destination writable stream closed before all data could be piped to it');
1438 if (preventCancel === false) {
1439 shutdownWithAction(() => ReadableStreamCancel(source, destClosed), true, destClosed);
1440 }
1441 else {
1442 shutdown(true, destClosed);
1443 }
1444 }
1445 setPromiseIsHandledToTrue(pipeLoop());
1446 function waitForWritesToFinish() {
1447 // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait
1448 // for that too.
1449 const oldCurrentWrite = currentWrite;
1450 return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined);
1451 }
1452 function isOrBecomesErrored(stream, promise, action) {
1453 if (stream._state === 'errored') {
1454 action(stream._storedError);
1455 }
1456 else {
1457 uponRejection(promise, action);
1458 }
1459 }
1460 function isOrBecomesClosed(stream, promise, action) {
1461 if (stream._state === 'closed') {
1462 action();
1463 }
1464 else {
1465 uponFulfillment(promise, action);
1466 }
1467 }
1468 function shutdownWithAction(action, originalIsError, originalError) {
1469 if (shuttingDown === true) {
1470 return;
1471 }
1472 shuttingDown = true;
1473 if (dest._state === 'writable' && WritableStreamCloseQueuedOrInFlight(dest) === false) {
1474 uponFulfillment(waitForWritesToFinish(), doTheRest);
1475 }
1476 else {
1477 doTheRest();
1478 }
1479 function doTheRest() {
1480 uponPromise(action(), () => finalize(originalIsError, originalError), newError => finalize(true, newError));
1481 }
1482 }
1483 function shutdown(isError, error) {
1484 if (shuttingDown === true) {
1485 return;
1486 }
1487 shuttingDown = true;
1488 if (dest._state === 'writable' && WritableStreamCloseQueuedOrInFlight(dest) === false) {
1489 uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error));
1490 }
1491 else {
1492 finalize(isError, error);
1493 }
1494 }
1495 function finalize(isError, error) {
1496 WritableStreamDefaultWriterRelease(writer);
1497 ReadableStreamReaderGenericRelease(reader);
1498 if (signal !== undefined) {
1499 signal.removeEventListener('abort', abortAlgorithm);
1500 }
1501 if (isError) {
1502 reject(error);
1503 }
1504 else {
1505 resolve(undefined);
1506 }
1507 }
1508 });
1509}
1510
1511class ReadableStreamDefaultController {
1512 /** @internal */
1513 constructor() {
1514 throw new TypeError();
1515 }
1516 get desiredSize() {
1517 if (IsReadableStreamDefaultController(this) === false) {
1518 throw defaultControllerBrandCheckException('desiredSize');
1519 }
1520 return ReadableStreamDefaultControllerGetDesiredSize(this);
1521 }
1522 close() {
1523 if (IsReadableStreamDefaultController(this) === false) {
1524 throw defaultControllerBrandCheckException('close');
1525 }
1526 if (ReadableStreamDefaultControllerCanCloseOrEnqueue(this) === false) {
1527 throw new TypeError('The stream is not in a state that permits close');
1528 }
1529 ReadableStreamDefaultControllerClose(this);
1530 }
1531 enqueue(chunk) {
1532 if (IsReadableStreamDefaultController(this) === false) {
1533 throw defaultControllerBrandCheckException('enqueue');
1534 }
1535 if (ReadableStreamDefaultControllerCanCloseOrEnqueue(this) === false) {
1536 throw new TypeError('The stream is not in a state that permits enqueue');
1537 }
1538 return ReadableStreamDefaultControllerEnqueue(this, chunk);
1539 }
1540 error(e) {
1541 if (IsReadableStreamDefaultController(this) === false) {
1542 throw defaultControllerBrandCheckException('error');
1543 }
1544 ReadableStreamDefaultControllerError(this, e);
1545 }
1546 /** @internal */
1547 [CancelSteps](reason) {
1548 ResetQueue(this);
1549 const result = this._cancelAlgorithm(reason);
1550 ReadableStreamDefaultControllerClearAlgorithms(this);
1551 return result;
1552 }
1553 /** @internal */
1554 [PullSteps]() {
1555 const stream = this._controlledReadableStream;
1556 if (this._queue.length > 0) {
1557 const chunk = DequeueValue(this);
1558 if (this._closeRequested === true && this._queue.length === 0) {
1559 ReadableStreamDefaultControllerClearAlgorithms(this);
1560 ReadableStreamClose(stream);
1561 }
1562 else {
1563 ReadableStreamDefaultControllerCallPullIfNeeded(this);
1564 }
1565 return promiseResolvedWith(ReadableStreamCreateReadResult(chunk, false, stream._reader._forAuthorCode));
1566 }
1567 const pendingPromise = ReadableStreamAddReadRequest(stream);
1568 ReadableStreamDefaultControllerCallPullIfNeeded(this);
1569 return pendingPromise;
1570 }
1571}
1572// Abstract operations for the ReadableStreamDefaultController.
1573function IsReadableStreamDefaultController(x) {
1574 if (!typeIsObject(x)) {
1575 return false;
1576 }
1577 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) {
1578 return false;
1579 }
1580 return true;
1581}
1582function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
1583 const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller);
1584 if (shouldPull === false) {
1585 return;
1586 }
1587 if (controller._pulling === true) {
1588 controller._pullAgain = true;
1589 return;
1590 }
1591 controller._pulling = true;
1592 const pullPromise = controller._pullAlgorithm();
1593 uponPromise(pullPromise, () => {
1594 controller._pulling = false;
1595 if (controller._pullAgain === true) {
1596 controller._pullAgain = false;
1597 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
1598 }
1599 }, e => {
1600 ReadableStreamDefaultControllerError(controller, e);
1601 });
1602}
1603function ReadableStreamDefaultControllerShouldCallPull(controller) {
1604 const stream = controller._controlledReadableStream;
1605 if (ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) === false) {
1606 return false;
1607 }
1608 if (controller._started === false) {
1609 return false;
1610 }
1611 if (IsReadableStreamLocked(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) {
1612 return true;
1613 }
1614 const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller);
1615 if (desiredSize > 0) {
1616 return true;
1617 }
1618 return false;
1619}
1620function ReadableStreamDefaultControllerClearAlgorithms(controller) {
1621 controller._pullAlgorithm = undefined;
1622 controller._cancelAlgorithm = undefined;
1623 controller._strategySizeAlgorithm = undefined;
1624}
1625// A client of ReadableStreamDefaultController may use these functions directly to bypass state check.
1626function ReadableStreamDefaultControllerClose(controller) {
1627 const stream = controller._controlledReadableStream;
1628 controller._closeRequested = true;
1629 if (controller._queue.length === 0) {
1630 ReadableStreamDefaultControllerClearAlgorithms(controller);
1631 ReadableStreamClose(stream);
1632 }
1633}
1634function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
1635 const stream = controller._controlledReadableStream;
1636 if (IsReadableStreamLocked(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) {
1637 ReadableStreamFulfillReadRequest(stream, chunk, false);
1638 }
1639 else {
1640 let chunkSize;
1641 try {
1642 chunkSize = controller._strategySizeAlgorithm(chunk);
1643 }
1644 catch (chunkSizeE) {
1645 ReadableStreamDefaultControllerError(controller, chunkSizeE);
1646 throw chunkSizeE;
1647 }
1648 try {
1649 EnqueueValueWithSize(controller, chunk, chunkSize);
1650 }
1651 catch (enqueueE) {
1652 ReadableStreamDefaultControllerError(controller, enqueueE);
1653 throw enqueueE;
1654 }
1655 }
1656 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
1657}
1658function ReadableStreamDefaultControllerError(controller, e) {
1659 const stream = controller._controlledReadableStream;
1660 if (stream._state !== 'readable') {
1661 return;
1662 }
1663 ResetQueue(controller);
1664 ReadableStreamDefaultControllerClearAlgorithms(controller);
1665 ReadableStreamError(stream, e);
1666}
1667function ReadableStreamDefaultControllerGetDesiredSize(controller) {
1668 const stream = controller._controlledReadableStream;
1669 const state = stream._state;
1670 if (state === 'errored') {
1671 return null;
1672 }
1673 if (state === 'closed') {
1674 return 0;
1675 }
1676 return controller._strategyHWM - controller._queueTotalSize;
1677}
1678// This is used in the implementation of TransformStream.
1679function ReadableStreamDefaultControllerHasBackpressure(controller) {
1680 if (ReadableStreamDefaultControllerShouldCallPull(controller) === true) {
1681 return false;
1682 }
1683 return true;
1684}
1685function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
1686 const state = controller._controlledReadableStream._state;
1687 if (controller._closeRequested === false && state === 'readable') {
1688 return true;
1689 }
1690 return false;
1691}
1692function SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm) {
1693 controller._controlledReadableStream = stream;
1694 controller._queue = undefined;
1695 controller._queueTotalSize = undefined;
1696 ResetQueue(controller);
1697 controller._started = false;
1698 controller._closeRequested = false;
1699 controller._pullAgain = false;
1700 controller._pulling = false;
1701 controller._strategySizeAlgorithm = sizeAlgorithm;
1702 controller._strategyHWM = highWaterMark;
1703 controller._pullAlgorithm = pullAlgorithm;
1704 controller._cancelAlgorithm = cancelAlgorithm;
1705 stream._readableStreamController = controller;
1706 const startResult = startAlgorithm();
1707 uponPromise(promiseResolvedWith(startResult), () => {
1708 controller._started = true;
1709 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
1710 }, r => {
1711 ReadableStreamDefaultControllerError(controller, r);
1712 });
1713}
1714function SetUpReadableStreamDefaultControllerFromUnderlyingSource(stream, underlyingSource, highWaterMark, sizeAlgorithm) {
1715 const controller = Object.create(ReadableStreamDefaultController.prototype);
1716 function startAlgorithm() {
1717 return InvokeOrNoop(underlyingSource, 'start', [controller]);
1718 }
1719 const pullAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingSource, 'pull', 0, [controller]);
1720 const cancelAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingSource, 'cancel', 1, []);
1721 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
1722}
1723// Helper functions for the ReadableStreamDefaultController.
1724function defaultControllerBrandCheckException(name) {
1725 return new TypeError(`ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`);
1726}
1727
1728function ReadableStreamTee(stream, cloneForBranch2) {
1729 const reader = AcquireReadableStreamDefaultReader(stream);
1730 let reading = false;
1731 let canceled1 = false;
1732 let canceled2 = false;
1733 let reason1;
1734 let reason2;
1735 let branch1;
1736 let branch2;
1737 let resolveCancelPromise;
1738 const cancelPromise = newPromise(resolve => {
1739 resolveCancelPromise = resolve;
1740 });
1741 function pullAlgorithm() {
1742 if (reading === true) {
1743 return promiseResolvedWith(undefined);
1744 }
1745 reading = true;
1746 const readPromise = transformPromiseWith(ReadableStreamDefaultReaderRead(reader), result => {
1747 reading = false;
1748 const done = result.done;
1749 if (done === true) {
1750 if (canceled1 === false) {
1751 ReadableStreamDefaultControllerClose(branch1._readableStreamController);
1752 }
1753 if (canceled2 === false) {
1754 ReadableStreamDefaultControllerClose(branch2._readableStreamController);
1755 }
1756 return;
1757 }
1758 const value = result.value;
1759 const value1 = value;
1760 const value2 = value;
1761 // There is no way to access the cloning code right now in the reference implementation.
1762 // If we add one then we'll need an implementation for serializable objects.
1763 // if (canceled2 === false && cloneForBranch2 === true) {
1764 // value2 = StructuredDeserialize(StructuredSerialize(value2));
1765 // }
1766 if (canceled1 === false) {
1767 ReadableStreamDefaultControllerEnqueue(branch1._readableStreamController, value1);
1768 }
1769 if (canceled2 === false) {
1770 ReadableStreamDefaultControllerEnqueue(branch2._readableStreamController, value2);
1771 }
1772 });
1773 setPromiseIsHandledToTrue(readPromise);
1774 return promiseResolvedWith(undefined);
1775 }
1776 function cancel1Algorithm(reason) {
1777 canceled1 = true;
1778 reason1 = reason;
1779 if (canceled2 === true) {
1780 const compositeReason = createArrayFromList([reason1, reason2]);
1781 const cancelResult = ReadableStreamCancel(stream, compositeReason);
1782 resolveCancelPromise(cancelResult);
1783 }
1784 return cancelPromise;
1785 }
1786 function cancel2Algorithm(reason) {
1787 canceled2 = true;
1788 reason2 = reason;
1789 if (canceled1 === true) {
1790 const compositeReason = createArrayFromList([reason1, reason2]);
1791 const cancelResult = ReadableStreamCancel(stream, compositeReason);
1792 resolveCancelPromise(cancelResult);
1793 }
1794 return cancelPromise;
1795 }
1796 function startAlgorithm() { }
1797 branch1 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm);
1798 branch2 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm);
1799 uponRejection(reader._closedPromise, (r) => {
1800 ReadableStreamDefaultControllerError(branch1._readableStreamController, r);
1801 ReadableStreamDefaultControllerError(branch2._readableStreamController, r);
1802 });
1803 return [branch1, branch2];
1804}
1805
1806/// <reference lib="es2015.core" />
1807// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger#Polyfill
1808const NumberIsInteger = Number.isInteger || function (value) {
1809 return typeof value === 'number' &&
1810 isFinite(value) &&
1811 Math.floor(value) === value;
1812};
1813
1814class ReadableStreamBYOBRequest {
1815 /** @internal */
1816 constructor() {
1817 throw new TypeError('ReadableStreamBYOBRequest cannot be used directly');
1818 }
1819 get view() {
1820 if (IsReadableStreamBYOBRequest(this) === false) {
1821 throw byobRequestBrandCheckException('view');
1822 }
1823 return this._view;
1824 }
1825 respond(bytesWritten) {
1826 if (IsReadableStreamBYOBRequest(this) === false) {
1827 throw byobRequestBrandCheckException('respond');
1828 }
1829 if (this._associatedReadableByteStreamController === undefined) {
1830 throw new TypeError('This BYOB request has been invalidated');
1831 }
1832 if (IsDetachedBuffer(this._view.buffer) === true) ;
1833 ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);
1834 }
1835 respondWithNewView(view) {
1836 if (IsReadableStreamBYOBRequest(this) === false) {
1837 throw byobRequestBrandCheckException('respond');
1838 }
1839 if (this._associatedReadableByteStreamController === undefined) {
1840 throw new TypeError('This BYOB request has been invalidated');
1841 }
1842 if (!ArrayBuffer.isView(view)) {
1843 throw new TypeError('You can only respond with array buffer views');
1844 }
1845 if (IsDetachedBuffer(view.buffer) === true) ;
1846 ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);
1847 }
1848}
1849class ReadableByteStreamController {
1850 /** @internal */
1851 constructor() {
1852 throw new TypeError('ReadableByteStreamController constructor cannot be used directly');
1853 }
1854 get byobRequest() {
1855 if (IsReadableByteStreamController(this) === false) {
1856 throw byteStreamControllerBrandCheckException('byobRequest');
1857 }
1858 if (this._byobRequest === undefined && this._pendingPullIntos.length > 0) {
1859 const firstDescriptor = this._pendingPullIntos.peek();
1860 const view = new Uint8Array(firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled);
1861 const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype);
1862 SetUpReadableStreamBYOBRequest(byobRequest, this, view);
1863 this._byobRequest = byobRequest;
1864 }
1865 return this._byobRequest;
1866 }
1867 get desiredSize() {
1868 if (IsReadableByteStreamController(this) === false) {
1869 throw byteStreamControllerBrandCheckException('desiredSize');
1870 }
1871 return ReadableByteStreamControllerGetDesiredSize(this);
1872 }
1873 close() {
1874 if (IsReadableByteStreamController(this) === false) {
1875 throw byteStreamControllerBrandCheckException('close');
1876 }
1877 if (this._closeRequested === true) {
1878 throw new TypeError('The stream has already been closed; do not close it again!');
1879 }
1880 const state = this._controlledReadableByteStream._state;
1881 if (state !== 'readable') {
1882 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);
1883 }
1884 ReadableByteStreamControllerClose(this);
1885 }
1886 enqueue(chunk) {
1887 if (IsReadableByteStreamController(this) === false) {
1888 throw byteStreamControllerBrandCheckException('enqueue');
1889 }
1890 if (this._closeRequested === true) {
1891 throw new TypeError('stream is closed or draining');
1892 }
1893 const state = this._controlledReadableByteStream._state;
1894 if (state !== 'readable') {
1895 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);
1896 }
1897 if (!ArrayBuffer.isView(chunk)) {
1898 throw new TypeError('You can only enqueue array buffer views when using a ReadableByteStreamController');
1899 }
1900 if (IsDetachedBuffer(chunk.buffer) === true) ;
1901 ReadableByteStreamControllerEnqueue(this, chunk);
1902 }
1903 error(e) {
1904 if (IsReadableByteStreamController(this) === false) {
1905 throw byteStreamControllerBrandCheckException('error');
1906 }
1907 ReadableByteStreamControllerError(this, e);
1908 }
1909 /** @internal */
1910 [CancelSteps](reason) {
1911 if (this._pendingPullIntos.length > 0) {
1912 const firstDescriptor = this._pendingPullIntos.peek();
1913 firstDescriptor.bytesFilled = 0;
1914 }
1915 ResetQueue(this);
1916 const result = this._cancelAlgorithm(reason);
1917 ReadableByteStreamControllerClearAlgorithms(this);
1918 return result;
1919 }
1920 /** @internal */
1921 [PullSteps]() {
1922 const stream = this._controlledReadableByteStream;
1923 if (this._queueTotalSize > 0) {
1924 const entry = this._queue.shift();
1925 this._queueTotalSize -= entry.byteLength;
1926 ReadableByteStreamControllerHandleQueueDrain(this);
1927 let view;
1928 try {
1929 view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);
1930 }
1931 catch (viewE) {
1932 return promiseRejectedWith(viewE);
1933 }
1934 return promiseResolvedWith(ReadableStreamCreateReadResult(view, false, stream._reader._forAuthorCode));
1935 }
1936 const autoAllocateChunkSize = this._autoAllocateChunkSize;
1937 if (autoAllocateChunkSize !== undefined) {
1938 let buffer;
1939 try {
1940 buffer = new ArrayBuffer(autoAllocateChunkSize);
1941 }
1942 catch (bufferE) {
1943 return promiseRejectedWith(bufferE);
1944 }
1945 const pullIntoDescriptor = {
1946 buffer,
1947 byteOffset: 0,
1948 byteLength: autoAllocateChunkSize,
1949 bytesFilled: 0,
1950 elementSize: 1,
1951 ctor: Uint8Array,
1952 readerType: 'default'
1953 };
1954 this._pendingPullIntos.push(pullIntoDescriptor);
1955 }
1956 const promise = ReadableStreamAddReadRequest(stream);
1957 ReadableByteStreamControllerCallPullIfNeeded(this);
1958 return promise;
1959 }
1960}
1961// Abstract operations for the ReadableByteStreamController.
1962function IsReadableByteStreamController(x) {
1963 if (!typeIsObject(x)) {
1964 return false;
1965 }
1966 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {
1967 return false;
1968 }
1969 return true;
1970}
1971function IsReadableStreamBYOBRequest(x) {
1972 if (!typeIsObject(x)) {
1973 return false;
1974 }
1975 if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {
1976 return false;
1977 }
1978 return true;
1979}
1980function ReadableByteStreamControllerCallPullIfNeeded(controller) {
1981 const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);
1982 if (shouldPull === false) {
1983 return;
1984 }
1985 if (controller._pulling === true) {
1986 controller._pullAgain = true;
1987 return;
1988 }
1989 controller._pulling = true;
1990 // TODO: Test controller argument
1991 const pullPromise = controller._pullAlgorithm();
1992 uponPromise(pullPromise, () => {
1993 controller._pulling = false;
1994 if (controller._pullAgain === true) {
1995 controller._pullAgain = false;
1996 ReadableByteStreamControllerCallPullIfNeeded(controller);
1997 }
1998 }, e => {
1999 ReadableByteStreamControllerError(controller, e);
2000 });
2001}
2002function ReadableByteStreamControllerClearPendingPullIntos(controller) {
2003 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
2004 controller._pendingPullIntos = new SimpleQueue();
2005}
2006function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) {
2007 let done = false;
2008 if (stream._state === 'closed') {
2009 done = true;
2010 }
2011 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
2012 if (pullIntoDescriptor.readerType === 'default') {
2013 ReadableStreamFulfillReadRequest(stream, filledView, done);
2014 }
2015 else {
2016 ReadableStreamFulfillReadIntoRequest(stream, filledView, done);
2017 }
2018}
2019function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) {
2020 const bytesFilled = pullIntoDescriptor.bytesFilled;
2021 const elementSize = pullIntoDescriptor.elementSize;
2022 return new pullIntoDescriptor.ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize);
2023}
2024function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) {
2025 controller._queue.push({ buffer, byteOffset, byteLength });
2026 controller._queueTotalSize += byteLength;
2027}
2028function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) {
2029 const elementSize = pullIntoDescriptor.elementSize;
2030 const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;
2031 const maxBytesToCopy = Math.min(controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);
2032 const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
2033 const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;
2034 let totalBytesToCopyRemaining = maxBytesToCopy;
2035 let ready = false;
2036 if (maxAlignedBytes > currentAlignedBytes) {
2037 totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;
2038 ready = true;
2039 }
2040 const queue = controller._queue;
2041 while (totalBytesToCopyRemaining > 0) {
2042 const headOfQueue = queue.peek();
2043 const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);
2044 const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
2045 ArrayBufferCopy(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);
2046 if (headOfQueue.byteLength === bytesToCopy) {
2047 queue.shift();
2048 }
2049 else {
2050 headOfQueue.byteOffset += bytesToCopy;
2051 headOfQueue.byteLength -= bytesToCopy;
2052 }
2053 controller._queueTotalSize -= bytesToCopy;
2054 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);
2055 totalBytesToCopyRemaining -= bytesToCopy;
2056 }
2057 return ready;
2058}
2059function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) {
2060 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
2061 pullIntoDescriptor.bytesFilled += size;
2062}
2063function ReadableByteStreamControllerHandleQueueDrain(controller) {
2064 if (controller._queueTotalSize === 0 && controller._closeRequested === true) {
2065 ReadableByteStreamControllerClearAlgorithms(controller);
2066 ReadableStreamClose(controller._controlledReadableByteStream);
2067 }
2068 else {
2069 ReadableByteStreamControllerCallPullIfNeeded(controller);
2070 }
2071}
2072function ReadableByteStreamControllerInvalidateBYOBRequest(controller) {
2073 if (controller._byobRequest === undefined) {
2074 return;
2075 }
2076 controller._byobRequest._associatedReadableByteStreamController = undefined;
2077 controller._byobRequest._view = undefined;
2078 controller._byobRequest = undefined;
2079}
2080function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) {
2081 while (controller._pendingPullIntos.length > 0) {
2082 if (controller._queueTotalSize === 0) {
2083 return;
2084 }
2085 const pullIntoDescriptor = controller._pendingPullIntos.peek();
2086 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) === true) {
2087 ReadableByteStreamControllerShiftPendingPullInto(controller);
2088 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
2089 }
2090 }
2091}
2092function ReadableByteStreamControllerPullInto(controller, view) {
2093 const stream = controller._controlledReadableByteStream;
2094 let elementSize = 1;
2095 if (view.constructor !== DataView) {
2096 elementSize = view.constructor.BYTES_PER_ELEMENT;
2097 }
2098 const ctor = view.constructor;
2099 const buffer = TransferArrayBuffer(view.buffer);
2100 const pullIntoDescriptor = {
2101 buffer,
2102 byteOffset: view.byteOffset,
2103 byteLength: view.byteLength,
2104 bytesFilled: 0,
2105 elementSize,
2106 ctor,
2107 readerType: 'byob'
2108 };
2109 if (controller._pendingPullIntos.length > 0) {
2110 controller._pendingPullIntos.push(pullIntoDescriptor);
2111 // No ReadableByteStreamControllerCallPullIfNeeded() call since:
2112 // - No change happens on desiredSize
2113 // - The source has already been notified of that there's at least 1 pending read(view)
2114 return ReadableStreamAddReadIntoRequest(stream);
2115 }
2116 if (stream._state === 'closed') {
2117 const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);
2118 return promiseResolvedWith(ReadableStreamCreateReadResult(emptyView, true, stream._reader._forAuthorCode));
2119 }
2120 if (controller._queueTotalSize > 0) {
2121 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) === true) {
2122 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
2123 ReadableByteStreamControllerHandleQueueDrain(controller);
2124 return promiseResolvedWith(ReadableStreamCreateReadResult(filledView, false, stream._reader._forAuthorCode));
2125 }
2126 if (controller._closeRequested === true) {
2127 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
2128 ReadableByteStreamControllerError(controller, e);
2129 return promiseRejectedWith(e);
2130 }
2131 }
2132 controller._pendingPullIntos.push(pullIntoDescriptor);
2133 const promise = ReadableStreamAddReadIntoRequest(stream);
2134 ReadableByteStreamControllerCallPullIfNeeded(controller);
2135 return promise;
2136}
2137function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) {
2138 firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);
2139 const stream = controller._controlledReadableByteStream;
2140 if (ReadableStreamHasBYOBReader(stream) === true) {
2141 while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {
2142 const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);
2143 ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);
2144 }
2145 }
2146}
2147function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) {
2148 if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength) {
2149 throw new RangeError('bytesWritten out of range');
2150 }
2151 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);
2152 if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {
2153 // TODO: Figure out whether we should detach the buffer or not here.
2154 return;
2155 }
2156 ReadableByteStreamControllerShiftPendingPullInto(controller);
2157 const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;
2158 if (remainderSize > 0) {
2159 const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
2160 const remainder = pullIntoDescriptor.buffer.slice(end - remainderSize, end);
2161 ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);
2162 }
2163 pullIntoDescriptor.buffer = TransferArrayBuffer(pullIntoDescriptor.buffer);
2164 pullIntoDescriptor.bytesFilled -= remainderSize;
2165 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
2166 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
2167}
2168function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) {
2169 const firstDescriptor = controller._pendingPullIntos.peek();
2170 const stream = controller._controlledReadableByteStream;
2171 if (stream._state === 'closed') {
2172 if (bytesWritten !== 0) {
2173 throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');
2174 }
2175 ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);
2176 }
2177 else {
2178 ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);
2179 }
2180 ReadableByteStreamControllerCallPullIfNeeded(controller);
2181}
2182function ReadableByteStreamControllerShiftPendingPullInto(controller) {
2183 const descriptor = controller._pendingPullIntos.shift();
2184 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
2185 return descriptor;
2186}
2187function ReadableByteStreamControllerShouldCallPull(controller) {
2188 const stream = controller._controlledReadableByteStream;
2189 if (stream._state !== 'readable') {
2190 return false;
2191 }
2192 if (controller._closeRequested === true) {
2193 return false;
2194 }
2195 if (controller._started === false) {
2196 return false;
2197 }
2198 if (ReadableStreamHasDefaultReader(stream) === true && ReadableStreamGetNumReadRequests(stream) > 0) {
2199 return true;
2200 }
2201 if (ReadableStreamHasBYOBReader(stream) === true && ReadableStreamGetNumReadIntoRequests(stream) > 0) {
2202 return true;
2203 }
2204 const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);
2205 if (desiredSize > 0) {
2206 return true;
2207 }
2208 return false;
2209}
2210function ReadableByteStreamControllerClearAlgorithms(controller) {
2211 controller._pullAlgorithm = undefined;
2212 controller._cancelAlgorithm = undefined;
2213}
2214// A client of ReadableByteStreamController may use these functions directly to bypass state check.
2215function ReadableByteStreamControllerClose(controller) {
2216 const stream = controller._controlledReadableByteStream;
2217 if (controller._queueTotalSize > 0) {
2218 controller._closeRequested = true;
2219 return;
2220 }
2221 if (controller._pendingPullIntos.length > 0) {
2222 const firstPendingPullInto = controller._pendingPullIntos.peek();
2223 if (firstPendingPullInto.bytesFilled > 0) {
2224 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
2225 ReadableByteStreamControllerError(controller, e);
2226 throw e;
2227 }
2228 }
2229 ReadableByteStreamControllerClearAlgorithms(controller);
2230 ReadableStreamClose(stream);
2231}
2232function ReadableByteStreamControllerEnqueue(controller, chunk) {
2233 const stream = controller._controlledReadableByteStream;
2234 const buffer = chunk.buffer;
2235 const byteOffset = chunk.byteOffset;
2236 const byteLength = chunk.byteLength;
2237 const transferredBuffer = TransferArrayBuffer(buffer);
2238 if (ReadableStreamHasDefaultReader(stream) === true) {
2239 if (ReadableStreamGetNumReadRequests(stream) === 0) {
2240 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
2241 }
2242 else {
2243 const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);
2244 ReadableStreamFulfillReadRequest(stream, transferredView, false);
2245 }
2246 }
2247 else if (ReadableStreamHasBYOBReader(stream) === true) {
2248 // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.
2249 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
2250 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
2251 }
2252 else {
2253 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
2254 }
2255 ReadableByteStreamControllerCallPullIfNeeded(controller);
2256}
2257function ReadableByteStreamControllerError(controller, e) {
2258 const stream = controller._controlledReadableByteStream;
2259 if (stream._state !== 'readable') {
2260 return;
2261 }
2262 ReadableByteStreamControllerClearPendingPullIntos(controller);
2263 ResetQueue(controller);
2264 ReadableByteStreamControllerClearAlgorithms(controller);
2265 ReadableStreamError(stream, e);
2266}
2267function ReadableByteStreamControllerGetDesiredSize(controller) {
2268 const stream = controller._controlledReadableByteStream;
2269 const state = stream._state;
2270 if (state === 'errored') {
2271 return null;
2272 }
2273 if (state === 'closed') {
2274 return 0;
2275 }
2276 return controller._strategyHWM - controller._queueTotalSize;
2277}
2278function ReadableByteStreamControllerRespond(controller, bytesWritten) {
2279 bytesWritten = Number(bytesWritten);
2280 if (IsFiniteNonNegativeNumber(bytesWritten) === false) {
2281 throw new RangeError('bytesWritten must be a finite');
2282 }
2283 ReadableByteStreamControllerRespondInternal(controller, bytesWritten);
2284}
2285function ReadableByteStreamControllerRespondWithNewView(controller, view) {
2286 const firstDescriptor = controller._pendingPullIntos.peek();
2287 if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {
2288 throw new RangeError('The region specified by view does not match byobRequest');
2289 }
2290 if (firstDescriptor.byteLength !== view.byteLength) {
2291 throw new RangeError('The buffer of view has different capacity than byobRequest');
2292 }
2293 firstDescriptor.buffer = view.buffer;
2294 ReadableByteStreamControllerRespondInternal(controller, view.byteLength);
2295}
2296function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize) {
2297 controller._controlledReadableByteStream = stream;
2298 controller._pullAgain = false;
2299 controller._pulling = false;
2300 controller._byobRequest = undefined;
2301 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
2302 controller._queue = controller._queueTotalSize = undefined;
2303 ResetQueue(controller);
2304 controller._closeRequested = false;
2305 controller._started = false;
2306 controller._strategyHWM = ValidateAndNormalizeHighWaterMark(highWaterMark);
2307 controller._pullAlgorithm = pullAlgorithm;
2308 controller._cancelAlgorithm = cancelAlgorithm;
2309 controller._autoAllocateChunkSize = autoAllocateChunkSize;
2310 controller._pendingPullIntos = new SimpleQueue();
2311 stream._readableStreamController = controller;
2312 const startResult = startAlgorithm();
2313 uponPromise(promiseResolvedWith(startResult), () => {
2314 controller._started = true;
2315 ReadableByteStreamControllerCallPullIfNeeded(controller);
2316 }, r => {
2317 ReadableByteStreamControllerError(controller, r);
2318 });
2319}
2320function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) {
2321 const controller = Object.create(ReadableByteStreamController.prototype);
2322 function startAlgorithm() {
2323 return InvokeOrNoop(underlyingByteSource, 'start', [controller]);
2324 }
2325 const pullAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingByteSource, 'pull', 0, [controller]);
2326 const cancelAlgorithm = CreateAlgorithmFromUnderlyingMethod(underlyingByteSource, 'cancel', 1, []);
2327 let autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;
2328 if (autoAllocateChunkSize !== undefined) {
2329 autoAllocateChunkSize = Number(autoAllocateChunkSize);
2330 if (NumberIsInteger(autoAllocateChunkSize) === false || autoAllocateChunkSize <= 0) {
2331 throw new RangeError('autoAllocateChunkSize must be a positive integer');
2332 }
2333 }
2334 SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize);
2335}
2336function SetUpReadableStreamBYOBRequest(request, controller, view) {
2337 request._associatedReadableByteStreamController = controller;
2338 request._view = view;
2339}
2340// Helper functions for the ReadableStreamBYOBRequest.
2341function byobRequestBrandCheckException(name) {
2342 return new TypeError(`ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);
2343}
2344// Helper functions for the ReadableByteStreamController.
2345function byteStreamControllerBrandCheckException(name) {
2346 return new TypeError(`ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);
2347}
2348
2349// Abstract operations for the ReadableStream.
2350function AcquireReadableStreamBYOBReader(stream, forAuthorCode = false) {
2351 const reader = new ReadableStreamBYOBReader(stream);
2352 reader._forAuthorCode = forAuthorCode;
2353 return reader;
2354}
2355// ReadableStream API exposed for controllers.
2356function ReadableStreamAddReadIntoRequest(stream) {
2357 const promise = newPromise((resolve, reject) => {
2358 const readIntoRequest = {
2359 _resolve: resolve,
2360 _reject: reject
2361 };
2362 stream._reader._readIntoRequests.push(readIntoRequest);
2363 });
2364 return promise;
2365}
2366function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) {
2367 const reader = stream._reader;
2368 const readIntoRequest = reader._readIntoRequests.shift();
2369 readIntoRequest._resolve(ReadableStreamCreateReadResult(chunk, done, reader._forAuthorCode));
2370}
2371function ReadableStreamGetNumReadIntoRequests(stream) {
2372 return stream._reader._readIntoRequests.length;
2373}
2374function ReadableStreamHasBYOBReader(stream) {
2375 const reader = stream._reader;
2376 if (reader === undefined) {
2377 return false;
2378 }
2379 if (!IsReadableStreamBYOBReader(reader)) {
2380 return false;
2381 }
2382 return true;
2383}
2384class ReadableStreamBYOBReader {
2385 constructor(stream) {
2386 if (!IsReadableStream(stream)) {
2387 throw new TypeError('ReadableStreamBYOBReader can only be constructed with a ReadableStream instance given a ' +
2388 'byte source');
2389 }
2390 if (IsReadableByteStreamController(stream._readableStreamController) === false) {
2391 throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' +
2392 'source');
2393 }
2394 if (IsReadableStreamLocked(stream)) {
2395 throw new TypeError('This stream has already been locked for exclusive reading by another reader');
2396 }
2397 ReadableStreamReaderGenericInitialize(this, stream);
2398 this._readIntoRequests = new SimpleQueue();
2399 }
2400 get closed() {
2401 if (!IsReadableStreamBYOBReader(this)) {
2402 return promiseRejectedWith(byobReaderBrandCheckException('closed'));
2403 }
2404 return this._closedPromise;
2405 }
2406 cancel(reason) {
2407 if (!IsReadableStreamBYOBReader(this)) {
2408 return promiseRejectedWith(byobReaderBrandCheckException('cancel'));
2409 }
2410 if (this._ownerReadableStream === undefined) {
2411 return promiseRejectedWith(readerLockException('cancel'));
2412 }
2413 return ReadableStreamReaderGenericCancel(this, reason);
2414 }
2415 read(view) {
2416 if (!IsReadableStreamBYOBReader(this)) {
2417 return promiseRejectedWith(byobReaderBrandCheckException('read'));
2418 }
2419 if (this._ownerReadableStream === undefined) {
2420 return promiseRejectedWith(readerLockException('read from'));
2421 }
2422 if (!ArrayBuffer.isView(view)) {
2423 return promiseRejectedWith(new TypeError('view must be an array buffer view'));
2424 }
2425 if (IsDetachedBuffer(view.buffer) === true) ;
2426 if (view.byteLength === 0) {
2427 return promiseRejectedWith(new TypeError('view must have non-zero byteLength'));
2428 }
2429 return ReadableStreamBYOBReaderRead(this, view);
2430 }
2431 releaseLock() {
2432 if (!IsReadableStreamBYOBReader(this)) {
2433 throw byobReaderBrandCheckException('releaseLock');
2434 }
2435 if (this._ownerReadableStream === undefined) {
2436 return;
2437 }
2438 if (this._readIntoRequests.length > 0) {
2439 throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
2440 }
2441 ReadableStreamReaderGenericRelease(this);
2442 }
2443}
2444// Abstract operations for the readers.
2445function IsReadableStreamBYOBReader(x) {
2446 if (!typeIsObject(x)) {
2447 return false;
2448 }
2449 if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) {
2450 return false;
2451 }
2452 return true;
2453}
2454function ReadableStreamBYOBReaderRead(reader, view) {
2455 const stream = reader._ownerReadableStream;
2456 stream._disturbed = true;
2457 if (stream._state === 'errored') {
2458 return promiseRejectedWith(stream._storedError);
2459 }
2460 // Controllers must implement this.
2461 return ReadableByteStreamControllerPullInto(stream._readableStreamController, view);
2462}
2463// Helper functions for the ReadableStreamBYOBReader.
2464function byobReaderBrandCheckException(name) {
2465 return new TypeError(`ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`);
2466}
2467
2468class ReadableStream {
2469 constructor(underlyingSource = {}, strategy = {}) {
2470 InitializeReadableStream(this);
2471 const size = strategy.size;
2472 let highWaterMark = strategy.highWaterMark;
2473 const type = underlyingSource.type;
2474 const typeString = String(type);
2475 if (typeString === 'bytes') {
2476 if (size !== undefined) {
2477 throw new RangeError('The strategy for a byte stream cannot have a size function');
2478 }
2479 if (highWaterMark === undefined) {
2480 highWaterMark = 0;
2481 }
2482 highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark);
2483 SetUpReadableByteStreamControllerFromUnderlyingSource(this, underlyingSource, highWaterMark);
2484 }
2485 else if (type === undefined) {
2486 const sizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(size);
2487 if (highWaterMark === undefined) {
2488 highWaterMark = 1;
2489 }
2490 highWaterMark = ValidateAndNormalizeHighWaterMark(highWaterMark);
2491 SetUpReadableStreamDefaultControllerFromUnderlyingSource(this, underlyingSource, highWaterMark, sizeAlgorithm);
2492 }
2493 else {
2494 throw new RangeError('Invalid type is specified');
2495 }
2496 }
2497 get locked() {
2498 if (IsReadableStream(this) === false) {
2499 throw streamBrandCheckException$1('locked');
2500 }
2501 return IsReadableStreamLocked(this);
2502 }
2503 cancel(reason) {
2504 if (IsReadableStream(this) === false) {
2505 return promiseRejectedWith(streamBrandCheckException$1('cancel'));
2506 }
2507 if (IsReadableStreamLocked(this) === true) {
2508 return promiseRejectedWith(new TypeError('Cannot cancel a stream that already has a reader'));
2509 }
2510 return ReadableStreamCancel(this, reason);
2511 }
2512 getReader({ mode } = {}) {
2513 if (IsReadableStream(this) === false) {
2514 throw streamBrandCheckException$1('getReader');
2515 }
2516 if (mode === undefined) {
2517 return AcquireReadableStreamDefaultReader(this, true);
2518 }
2519 mode = String(mode);
2520 if (mode === 'byob') {
2521 return AcquireReadableStreamBYOBReader(this, true);
2522 }
2523 throw new RangeError('Invalid mode is specified');
2524 }
2525 pipeThrough({ writable, readable }, { preventClose, preventAbort, preventCancel, signal } = {}) {
2526 if (IsReadableStream(this) === false) {
2527 throw streamBrandCheckException$1('pipeThrough');
2528 }
2529 if (IsWritableStream(writable) === false) {
2530 throw new TypeError('writable argument to pipeThrough must be a WritableStream');
2531 }
2532 if (IsReadableStream(readable) === false) {
2533 throw new TypeError('readable argument to pipeThrough must be a ReadableStream');
2534 }
2535 preventClose = Boolean(preventClose);
2536 preventAbort = Boolean(preventAbort);
2537 preventCancel = Boolean(preventCancel);
2538 if (signal !== undefined && !isAbortSignal(signal)) {
2539 throw new TypeError('ReadableStream.prototype.pipeThrough\'s signal option must be an AbortSignal');
2540 }
2541 if (IsReadableStreamLocked(this) === true) {
2542 throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream');
2543 }
2544 if (IsWritableStreamLocked(writable) === true) {
2545 throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream');
2546 }
2547 const promise = ReadableStreamPipeTo(this, writable, preventClose, preventAbort, preventCancel, signal);
2548 setPromiseIsHandledToTrue(promise);
2549 return readable;
2550 }
2551 pipeTo(dest, { preventClose, preventAbort, preventCancel, signal } = {}) {
2552 if (IsReadableStream(this) === false) {
2553 return promiseRejectedWith(streamBrandCheckException$1('pipeTo'));
2554 }
2555 if (IsWritableStream(dest) === false) {
2556 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo\'s first argument must be a WritableStream'));
2557 }
2558 preventClose = Boolean(preventClose);
2559 preventAbort = Boolean(preventAbort);
2560 preventCancel = Boolean(preventCancel);
2561 if (signal !== undefined && !isAbortSignal(signal)) {
2562 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo\'s signal option must be an AbortSignal'));
2563 }
2564 if (IsReadableStreamLocked(this) === true) {
2565 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream'));
2566 }
2567 if (IsWritableStreamLocked(dest) === true) {
2568 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream'));
2569 }
2570 return ReadableStreamPipeTo(this, dest, preventClose, preventAbort, preventCancel, signal);
2571 }
2572 tee() {
2573 if (IsReadableStream(this) === false) {
2574 throw streamBrandCheckException$1('tee');
2575 }
2576 const branches = ReadableStreamTee(this);
2577 return createArrayFromList(branches);
2578 }
2579 getIterator({ preventCancel = false } = {}) {
2580 if (IsReadableStream(this) === false) {
2581 throw streamBrandCheckException$1('getIterator');
2582 }
2583 return AcquireReadableStreamAsyncIterator(this, preventCancel);
2584 }
2585}
2586if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
2587 Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.asyncIterator, {
2588 value: ReadableStream.prototype.getIterator,
2589 enumerable: false,
2590 writable: true,
2591 configurable: true
2592 });
2593}
2594// Abstract operations for the ReadableStream.
2595// Throws if and only if startAlgorithm throws.
2596function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
2597 const stream = Object.create(ReadableStream.prototype);
2598 InitializeReadableStream(stream);
2599 const controller = Object.create(ReadableStreamDefaultController.prototype);
2600 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
2601 return stream;
2602}
2603function InitializeReadableStream(stream) {
2604 stream._state = 'readable';
2605 stream._reader = undefined;
2606 stream._storedError = undefined;
2607 stream._disturbed = false;
2608}
2609function IsReadableStream(x) {
2610 if (!typeIsObject(x)) {
2611 return false;
2612 }
2613 if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) {
2614 return false;
2615 }
2616 return true;
2617}
2618function IsReadableStreamLocked(stream) {
2619 if (stream._reader === undefined) {
2620 return false;
2621 }
2622 return true;
2623}
2624// ReadableStream API exposed for controllers.
2625function ReadableStreamCancel(stream, reason) {
2626 stream._disturbed = true;
2627 if (stream._state === 'closed') {
2628 return promiseResolvedWith(undefined);
2629 }
2630 if (stream._state === 'errored') {
2631 return promiseRejectedWith(stream._storedError);
2632 }
2633 ReadableStreamClose(stream);
2634 const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason);
2635 return transformPromiseWith(sourceCancelPromise, noop);
2636}
2637function ReadableStreamClose(stream) {
2638 stream._state = 'closed';
2639 const reader = stream._reader;
2640 if (reader === undefined) {
2641 return;
2642 }
2643 if (IsReadableStreamDefaultReader(reader)) {
2644 reader._readRequests.forEach(readRequest => {
2645 readRequest._resolve(ReadableStreamCreateReadResult(undefined, true, reader._forAuthorCode));
2646 });
2647 reader._readRequests = new SimpleQueue();
2648 }
2649 defaultReaderClosedPromiseResolve(reader);
2650}
2651function ReadableStreamError(stream, e) {
2652 stream._state = 'errored';
2653 stream._storedError = e;
2654 const reader = stream._reader;
2655 if (reader === undefined) {
2656 return;
2657 }
2658 if (IsReadableStreamDefaultReader(reader)) {
2659 reader._readRequests.forEach(readRequest => {
2660 readRequest._reject(e);
2661 });
2662 reader._readRequests = new SimpleQueue();
2663 }
2664 else {
2665 reader._readIntoRequests.forEach(readIntoRequest => {
2666 readIntoRequest._reject(e);
2667 });
2668 reader._readIntoRequests = new SimpleQueue();
2669 }
2670 defaultReaderClosedPromiseReject(reader, e);
2671}
2672// Helper functions for the ReadableStream.
2673function streamBrandCheckException$1(name) {
2674 return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`);
2675}
2676
2677// Class TransformStream
2678class TransformStream {
2679 constructor(transformer = {}, writableStrategy = {}, readableStrategy = {}) {
2680 const writableSizeFunction = writableStrategy.size;
2681 let writableHighWaterMark = writableStrategy.highWaterMark;
2682 const readableSizeFunction = readableStrategy.size;
2683 let readableHighWaterMark = readableStrategy.highWaterMark;
2684 const writableType = transformer.writableType;
2685 if (writableType !== undefined) {
2686 throw new RangeError('Invalid writable type specified');
2687 }
2688 const writableSizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(writableSizeFunction);
2689 if (writableHighWaterMark === undefined) {
2690 writableHighWaterMark = 1;
2691 }
2692 writableHighWaterMark = ValidateAndNormalizeHighWaterMark(writableHighWaterMark);
2693 const readableType = transformer.readableType;
2694 if (readableType !== undefined) {
2695 throw new RangeError('Invalid readable type specified');
2696 }
2697 const readableSizeAlgorithm = MakeSizeAlgorithmFromSizeFunction(readableSizeFunction);
2698 if (readableHighWaterMark === undefined) {
2699 readableHighWaterMark = 0;
2700 }
2701 readableHighWaterMark = ValidateAndNormalizeHighWaterMark(readableHighWaterMark);
2702 let startPromise_resolve;
2703 const startPromise = newPromise(resolve => {
2704 startPromise_resolve = resolve;
2705 });
2706 InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
2707 SetUpTransformStreamDefaultControllerFromTransformer(this, transformer);
2708 const startResult = InvokeOrNoop(transformer, 'start', [this._transformStreamController]);
2709 startPromise_resolve(startResult);
2710 }
2711 get readable() {
2712 if (IsTransformStream(this) === false) {
2713 throw streamBrandCheckException$2('readable');
2714 }
2715 return this._readable;
2716 }
2717 get writable() {
2718 if (IsTransformStream(this) === false) {
2719 throw streamBrandCheckException$2('writable');
2720 }
2721 return this._writable;
2722 }
2723}
2724function InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
2725 function startAlgorithm() {
2726 return startPromise;
2727 }
2728 function writeAlgorithm(chunk) {
2729 return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk);
2730 }
2731 function abortAlgorithm(reason) {
2732 return TransformStreamDefaultSinkAbortAlgorithm(stream, reason);
2733 }
2734 function closeAlgorithm() {
2735 return TransformStreamDefaultSinkCloseAlgorithm(stream);
2736 }
2737 stream._writable = CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm);
2738 function pullAlgorithm() {
2739 return TransformStreamDefaultSourcePullAlgorithm(stream);
2740 }
2741 function cancelAlgorithm(reason) {
2742 TransformStreamErrorWritableAndUnblockWrite(stream, reason);
2743 return promiseResolvedWith(undefined);
2744 }
2745 stream._readable = CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
2746 // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure.
2747 stream._backpressure = undefined;
2748 stream._backpressureChangePromise = undefined;
2749 stream._backpressureChangePromise_resolve = undefined;
2750 TransformStreamSetBackpressure(stream, true);
2751 // Used by IsWritableStream() which is called by SetUpTransformStreamDefaultController().
2752 stream._transformStreamController = undefined;
2753}
2754function IsTransformStream(x) {
2755 if (!typeIsObject(x)) {
2756 return false;
2757 }
2758 if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) {
2759 return false;
2760 }
2761 return true;
2762}
2763// This is a no-op if both sides are already errored.
2764function TransformStreamError(stream, e) {
2765 ReadableStreamDefaultControllerError(stream._readable._readableStreamController, e);
2766 TransformStreamErrorWritableAndUnblockWrite(stream, e);
2767}
2768function TransformStreamErrorWritableAndUnblockWrite(stream, e) {
2769 TransformStreamDefaultControllerClearAlgorithms(stream._transformStreamController);
2770 WritableStreamDefaultControllerErrorIfNeeded(stream._writable._writableStreamController, e);
2771 if (stream._backpressure === true) {
2772 // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure()
2773 // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time
2774 // _backpressure is set.
2775 TransformStreamSetBackpressure(stream, false);
2776 }
2777}
2778function TransformStreamSetBackpressure(stream, backpressure) {
2779 // Passes also when called during construction.
2780 if (stream._backpressureChangePromise !== undefined) {
2781 stream._backpressureChangePromise_resolve();
2782 }
2783 stream._backpressureChangePromise = newPromise(resolve => {
2784 stream._backpressureChangePromise_resolve = resolve;
2785 });
2786 stream._backpressure = backpressure;
2787}
2788class TransformStreamDefaultController {
2789 /** @internal */
2790 constructor() {
2791 throw new TypeError('TransformStreamDefaultController instances cannot be created directly');
2792 }
2793 get desiredSize() {
2794 if (IsTransformStreamDefaultController(this) === false) {
2795 throw defaultControllerBrandCheckException$1('desiredSize');
2796 }
2797 const readableController = this._controlledTransformStream._readable._readableStreamController;
2798 return ReadableStreamDefaultControllerGetDesiredSize(readableController);
2799 }
2800 enqueue(chunk) {
2801 if (IsTransformStreamDefaultController(this) === false) {
2802 throw defaultControllerBrandCheckException$1('enqueue');
2803 }
2804 TransformStreamDefaultControllerEnqueue(this, chunk);
2805 }
2806 error(reason) {
2807 if (IsTransformStreamDefaultController(this) === false) {
2808 throw defaultControllerBrandCheckException$1('error');
2809 }
2810 TransformStreamDefaultControllerError(this, reason);
2811 }
2812 terminate() {
2813 if (IsTransformStreamDefaultController(this) === false) {
2814 throw defaultControllerBrandCheckException$1('terminate');
2815 }
2816 TransformStreamDefaultControllerTerminate(this);
2817 }
2818}
2819// Transform Stream Default Controller Abstract Operations
2820function IsTransformStreamDefaultController(x) {
2821 if (!typeIsObject(x)) {
2822 return false;
2823 }
2824 if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) {
2825 return false;
2826 }
2827 return true;
2828}
2829function SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm) {
2830 controller._controlledTransformStream = stream;
2831 stream._transformStreamController = controller;
2832 controller._transformAlgorithm = transformAlgorithm;
2833 controller._flushAlgorithm = flushAlgorithm;
2834}
2835function SetUpTransformStreamDefaultControllerFromTransformer(stream, transformer) {
2836 const controller = Object.create(TransformStreamDefaultController.prototype);
2837 let transformAlgorithm = (chunk) => {
2838 try {
2839 TransformStreamDefaultControllerEnqueue(controller, chunk);
2840 return promiseResolvedWith(undefined);
2841 }
2842 catch (transformResultE) {
2843 return promiseRejectedWith(transformResultE);
2844 }
2845 };
2846 const transformMethod = transformer.transform;
2847 if (transformMethod !== undefined) {
2848 if (typeof transformMethod !== 'function') {
2849 throw new TypeError('transform is not a method');
2850 }
2851 transformAlgorithm = chunk => PromiseCall(transformMethod, transformer, [chunk, controller]);
2852 }
2853 const flushAlgorithm = CreateAlgorithmFromUnderlyingMethod(transformer, 'flush', 0, [controller]);
2854 SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm);
2855}
2856function TransformStreamDefaultControllerClearAlgorithms(controller) {
2857 controller._transformAlgorithm = undefined;
2858 controller._flushAlgorithm = undefined;
2859}
2860function TransformStreamDefaultControllerEnqueue(controller, chunk) {
2861 const stream = controller._controlledTransformStream;
2862 const readableController = stream._readable._readableStreamController;
2863 if (ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController) === false) {
2864 throw new TypeError('Readable side is not in a state that permits enqueue');
2865 }
2866 // We throttle transform invocations based on the backpressure of the ReadableStream, but we still
2867 // accept TransformStreamDefaultControllerEnqueue() calls.
2868 try {
2869 ReadableStreamDefaultControllerEnqueue(readableController, chunk);
2870 }
2871 catch (e) {
2872 // This happens when readableStrategy.size() throws.
2873 TransformStreamErrorWritableAndUnblockWrite(stream, e);
2874 throw stream._readable._storedError;
2875 }
2876 const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController);
2877 if (backpressure !== stream._backpressure) {
2878 TransformStreamSetBackpressure(stream, true);
2879 }
2880}
2881function TransformStreamDefaultControllerError(controller, e) {
2882 TransformStreamError(controller._controlledTransformStream, e);
2883}
2884function TransformStreamDefaultControllerPerformTransform(controller, chunk) {
2885 const transformPromise = controller._transformAlgorithm(chunk);
2886 return transformPromiseWith(transformPromise, undefined, r => {
2887 TransformStreamError(controller._controlledTransformStream, r);
2888 throw r;
2889 });
2890}
2891function TransformStreamDefaultControllerTerminate(controller) {
2892 const stream = controller._controlledTransformStream;
2893 const readableController = stream._readable._readableStreamController;
2894 if (ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController) === true) {
2895 ReadableStreamDefaultControllerClose(readableController);
2896 }
2897 const error = new TypeError('TransformStream terminated');
2898 TransformStreamErrorWritableAndUnblockWrite(stream, error);
2899}
2900// TransformStreamDefaultSink Algorithms
2901function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
2902 const controller = stream._transformStreamController;
2903 if (stream._backpressure === true) {
2904 const backpressureChangePromise = stream._backpressureChangePromise;
2905 return transformPromiseWith(backpressureChangePromise, () => {
2906 const writable = stream._writable;
2907 const state = writable._state;
2908 if (state === 'erroring') {
2909 throw writable._storedError;
2910 }
2911 return TransformStreamDefaultControllerPerformTransform(controller, chunk);
2912 });
2913 }
2914 return TransformStreamDefaultControllerPerformTransform(controller, chunk);
2915}
2916function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) {
2917 // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already
2918 // errored.
2919 TransformStreamError(stream, reason);
2920 return promiseResolvedWith(undefined);
2921}
2922function TransformStreamDefaultSinkCloseAlgorithm(stream) {
2923 // stream._readable cannot change after construction, so caching it across a call to user code is safe.
2924 const readable = stream._readable;
2925 const controller = stream._transformStreamController;
2926 const flushPromise = controller._flushAlgorithm();
2927 TransformStreamDefaultControllerClearAlgorithms(controller);
2928 // Return a promise that is fulfilled with undefined on success.
2929 return transformPromiseWith(flushPromise, () => {
2930 if (readable._state === 'errored') {
2931 throw readable._storedError;
2932 }
2933 const readableController = readable._readableStreamController;
2934 if (ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController) === true) {
2935 ReadableStreamDefaultControllerClose(readableController);
2936 }
2937 }, r => {
2938 TransformStreamError(stream, r);
2939 throw readable._storedError;
2940 });
2941}
2942// TransformStreamDefaultSource Algorithms
2943function TransformStreamDefaultSourcePullAlgorithm(stream) {
2944 // Invariant. Enforced by the promises returned by start() and pull().
2945 TransformStreamSetBackpressure(stream, false);
2946 // Prevent the next pull() call until there is backpressure.
2947 return stream._backpressureChangePromise;
2948}
2949// Helper functions for the TransformStreamDefaultController.
2950function defaultControllerBrandCheckException$1(name) {
2951 return new TypeError(`TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`);
2952}
2953// Helper functions for the TransformStream.
2954function streamBrandCheckException$2(name) {
2955 return new TypeError(`TransformStream.prototype.${name} can only be used on a TransformStream`);
2956}
2957
2958/*! *****************************************************************************
2959Copyright (c) Microsoft Corporation. All rights reserved.
2960Licensed under the Apache License, Version 2.0 (the "License"); you may not use
2961this file except in compliance with the License. You may obtain a copy of the
2962License at http://www.apache.org/licenses/LICENSE-2.0
2963
2964THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
2965KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
2966WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
2967MERCHANTABLITY OR NON-INFRINGEMENT.
2968
2969See the Apache Version 2.0 License for specific language governing permissions
2970and limitations under the License.
2971***************************************************************************** */
2972/* global Reflect, Promise */
2973
2974var extendStatics = function(d, b) {
2975 extendStatics = Object.setPrototypeOf ||
2976 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
2977 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
2978 return extendStatics(d, b);
2979};
2980
2981function __extends(d, b) {
2982 extendStatics(d, b);
2983 function __() { this.constructor = d; }
2984 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
2985}
2986
2987function assert(test) {
2988 if (!test) {
2989 throw new TypeError('Assertion failed');
2990 }
2991}
2992
2993function noop$1() {
2994 return;
2995}
2996function typeIsObject$1(x) {
2997 return (typeof x === 'object' && x !== null) || typeof x === 'function';
2998}
2999
3000function isStreamConstructor(ctor) {
3001 if (typeof ctor !== 'function') {
3002 return false;
3003 }
3004 var startCalled = false;
3005 try {
3006 new ctor({
3007 start: function () {
3008 startCalled = true;
3009 }
3010 });
3011 }
3012 catch (e) {
3013 // ignore
3014 }
3015 return startCalled;
3016}
3017function isReadableStream(readable) {
3018 if (!typeIsObject$1(readable)) {
3019 return false;
3020 }
3021 if (typeof readable.getReader !== 'function') {
3022 return false;
3023 }
3024 return true;
3025}
3026function isReadableStreamConstructor(ctor) {
3027 if (!isStreamConstructor(ctor)) {
3028 return false;
3029 }
3030 if (!isReadableStream(new ctor())) {
3031 return false;
3032 }
3033 return true;
3034}
3035function supportsByobReader(readable) {
3036 try {
3037 var reader = readable.getReader({ mode: 'byob' });
3038 reader.releaseLock();
3039 return true;
3040 }
3041 catch (_a) {
3042 return false;
3043 }
3044}
3045function supportsByteSource(ctor) {
3046 try {
3047 new ctor({ type: 'bytes' });
3048 return true;
3049 }
3050 catch (_a) {
3051 return false;
3052 }
3053}
3054
3055function createReadableStreamWrapper(ctor) {
3056 assert(isReadableStreamConstructor(ctor));
3057 var byteSourceSupported = supportsByteSource(ctor);
3058 return function (readable, _a) {
3059 var type = (_a === void 0 ? {} : _a).type;
3060 type = parseReadableType(type);
3061 if (type === 'bytes' && !byteSourceSupported) {
3062 type = undefined;
3063 }
3064 if (readable.constructor === ctor) {
3065 if (type !== 'bytes' || supportsByobReader(readable)) {
3066 return readable;
3067 }
3068 }
3069 var source = createWrappingReadableSource(readable, { type: type });
3070 return new ctor(source);
3071 };
3072}
3073function createWrappingReadableSource(readable, _a) {
3074 var type = (_a === void 0 ? {} : _a).type;
3075 assert(isReadableStream(readable));
3076 assert(readable.locked === false);
3077 type = parseReadableType(type);
3078 var source;
3079 if (type === 'bytes') {
3080 source = new WrappingReadableByteStreamSource(readable);
3081 }
3082 else {
3083 source = new WrappingReadableStreamDefaultSource(readable);
3084 }
3085 return source;
3086}
3087function parseReadableType(type) {
3088 var typeString = String(type);
3089 if (typeString === 'bytes') {
3090 return typeString;
3091 }
3092 else if (type === undefined) {
3093 return type;
3094 }
3095 else {
3096 throw new RangeError('Invalid type is specified');
3097 }
3098}
3099var AbstractWrappingReadableStreamSource = /** @class */ (function () {
3100 function AbstractWrappingReadableStreamSource(underlyingStream) {
3101 this._underlyingReader = undefined;
3102 this._readerMode = undefined;
3103 this._readableStreamController = undefined;
3104 this._pendingRead = undefined;
3105 this._underlyingStream = underlyingStream;
3106 // always keep a reader attached to detect close/error
3107 this._attachDefaultReader();
3108 }
3109 AbstractWrappingReadableStreamSource.prototype.start = function (controller) {
3110 this._readableStreamController = controller;
3111 };
3112 AbstractWrappingReadableStreamSource.prototype.cancel = function (reason) {
3113 assert(this._underlyingReader !== undefined);
3114 return this._underlyingReader.cancel(reason);
3115 };
3116 AbstractWrappingReadableStreamSource.prototype._attachDefaultReader = function () {
3117 if (this._readerMode === "default" /* DEFAULT */) {
3118 return;
3119 }
3120 this._detachReader();
3121 var reader = this._underlyingStream.getReader();
3122 this._readerMode = "default" /* DEFAULT */;
3123 this._attachReader(reader);
3124 };
3125 AbstractWrappingReadableStreamSource.prototype._attachReader = function (reader) {
3126 var _this = this;
3127 assert(this._underlyingReader === undefined);
3128 this._underlyingReader = reader;
3129 var closed = this._underlyingReader.closed;
3130 if (!closed) {
3131 return;
3132 }
3133 closed
3134 .then(function () { return _this._finishPendingRead(); })
3135 .then(function () {
3136 if (reader === _this._underlyingReader) {
3137 _this._readableStreamController.close();
3138 }
3139 }, function (reason) {
3140 if (reader === _this._underlyingReader) {
3141 _this._readableStreamController.error(reason);
3142 }
3143 })
3144 .catch(noop$1);
3145 };
3146 AbstractWrappingReadableStreamSource.prototype._detachReader = function () {
3147 if (this._underlyingReader === undefined) {
3148 return;
3149 }
3150 this._underlyingReader.releaseLock();
3151 this._underlyingReader = undefined;
3152 this._readerMode = undefined;
3153 };
3154 AbstractWrappingReadableStreamSource.prototype._pullWithDefaultReader = function () {
3155 var _this = this;
3156 this._attachDefaultReader();
3157 // TODO Backpressure?
3158 var read = this._underlyingReader.read()
3159 .then(function (result) {
3160 var controller = _this._readableStreamController;
3161 if (result.done) {
3162 _this._tryClose();
3163 }
3164 else {
3165 controller.enqueue(result.value);
3166 }
3167 });
3168 this._setPendingRead(read);
3169 return read;
3170 };
3171 AbstractWrappingReadableStreamSource.prototype._tryClose = function () {
3172 try {
3173 this._readableStreamController.close();
3174 }
3175 catch (_a) {
3176 // already errored or closed
3177 }
3178 };
3179 AbstractWrappingReadableStreamSource.prototype._setPendingRead = function (readPromise) {
3180 var _this = this;
3181 var pendingRead;
3182 var finishRead = function () {
3183 if (_this._pendingRead === pendingRead) {
3184 _this._pendingRead = undefined;
3185 }
3186 };
3187 this._pendingRead = pendingRead = readPromise.then(finishRead, finishRead);
3188 };
3189 AbstractWrappingReadableStreamSource.prototype._finishPendingRead = function () {
3190 var _this = this;
3191 if (!this._pendingRead) {
3192 return undefined;
3193 }
3194 var afterRead = function () { return _this._finishPendingRead(); };
3195 return this._pendingRead.then(afterRead, afterRead);
3196 };
3197 return AbstractWrappingReadableStreamSource;
3198}());
3199var WrappingReadableStreamDefaultSource = /** @class */ (function (_super) {
3200 __extends(WrappingReadableStreamDefaultSource, _super);
3201 function WrappingReadableStreamDefaultSource() {
3202 return _super !== null && _super.apply(this, arguments) || this;
3203 }
3204 WrappingReadableStreamDefaultSource.prototype.pull = function () {
3205 return this._pullWithDefaultReader();
3206 };
3207 return WrappingReadableStreamDefaultSource;
3208}(AbstractWrappingReadableStreamSource));
3209function toUint8Array(view) {
3210 return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
3211}
3212function copyArrayBufferView(from, to) {
3213 var fromArray = toUint8Array(from);
3214 var toArray = toUint8Array(to);
3215 toArray.set(fromArray, 0);
3216}
3217var WrappingReadableByteStreamSource = /** @class */ (function (_super) {
3218 __extends(WrappingReadableByteStreamSource, _super);
3219 function WrappingReadableByteStreamSource(underlyingStream) {
3220 var _this = this;
3221 var supportsByob = supportsByobReader(underlyingStream);
3222 _this = _super.call(this, underlyingStream) || this;
3223 _this._supportsByob = supportsByob;
3224 return _this;
3225 }
3226 Object.defineProperty(WrappingReadableByteStreamSource.prototype, "type", {
3227 get: function () {
3228 return 'bytes';
3229 },
3230 enumerable: true,
3231 configurable: true
3232 });
3233 WrappingReadableByteStreamSource.prototype._attachByobReader = function () {
3234 if (this._readerMode === "byob" /* BYOB */) {
3235 return;
3236 }
3237 assert(this._supportsByob);
3238 this._detachReader();
3239 var reader = this._underlyingStream.getReader({ mode: 'byob' });
3240 this._readerMode = "byob" /* BYOB */;
3241 this._attachReader(reader);
3242 };
3243 WrappingReadableByteStreamSource.prototype.pull = function () {
3244 if (this._supportsByob) {
3245 var byobRequest = this._readableStreamController.byobRequest;
3246 if (byobRequest !== undefined) {
3247 return this._pullWithByobRequest(byobRequest);
3248 }
3249 }
3250 return this._pullWithDefaultReader();
3251 };
3252 WrappingReadableByteStreamSource.prototype._pullWithByobRequest = function (byobRequest) {
3253 var _this = this;
3254 this._attachByobReader();
3255 // reader.read(view) detaches the input view, therefore we cannot pass byobRequest.view directly
3256 // create a separate buffer to read into, then copy that to byobRequest.view
3257 var buffer = new Uint8Array(byobRequest.view.byteLength);
3258 // TODO Backpressure?
3259 var read = this._underlyingReader.read(buffer)
3260 .then(function (result) {
3261 _this._readableStreamController;
3262 if (result.done) {
3263 _this._tryClose();
3264 byobRequest.respond(0);
3265 }
3266 else {
3267 copyArrayBufferView(result.value, byobRequest.view);
3268 byobRequest.respond(result.value.byteLength);
3269 }
3270 });
3271 this._setPendingRead(read);
3272 return read;
3273 };
3274 return WrappingReadableByteStreamSource;
3275}(AbstractWrappingReadableStreamSource));
3276
3277const isNode = typeof globalThis.process === 'object' &&
3278 typeof globalThis.process.versions === 'object';
3279
3280const NodeReadableStream = isNode && void('stream').Readable;
3281
3282/**
3283 * Check whether data is a Stream, and if so of which type
3284 * @param {Any} input data to check
3285 * @returns {'web'|'ponyfill'|'node'|false}
3286 */
3287function isStream(input) {
3288 if (globalThis.ReadableStream && globalThis.ReadableStream.prototype.isPrototypeOf(input)) {
3289 return 'web';
3290 }
3291 if (stream.ReadableStream.prototype.isPrototypeOf(input)) {
3292 return 'ponyfill';
3293 }
3294 if (NodeReadableStream && NodeReadableStream.prototype.isPrototypeOf(input)) {
3295 return 'node';
3296 }
3297 return false;
3298}
3299
3300/**
3301 * Check whether data is a Uint8Array
3302 * @param {Any} input data to check
3303 * @returns {Boolean}
3304 */
3305function isUint8Array(input) {
3306 return Uint8Array.prototype.isPrototypeOf(input);
3307}
3308
3309/**
3310 * Concat Uint8Arrays
3311 * @param {Array<Uint8array>} Array of Uint8Arrays to concatenate
3312 * @returns {Uint8array} Concatenated array
3313 */
3314function concatUint8Array(arrays) {
3315 if (arrays.length === 1) return arrays[0];
3316
3317 let totalLength = 0;
3318 for (let i = 0; i < arrays.length; i++) {
3319 if (!isUint8Array(arrays[i])) {
3320 throw new Error('concatUint8Array: Data must be in the form of a Uint8Array');
3321 }
3322
3323 totalLength += arrays[i].length;
3324 }
3325
3326 const result = new Uint8Array(totalLength);
3327 let pos = 0;
3328 arrays.forEach(function (element) {
3329 result.set(element, pos);
3330 pos += element.length;
3331 });
3332
3333 return result;
3334}
3335
3336const NodeBuffer = isNode && void('buffer').Buffer;
3337const NodeReadableStream$1 = isNode && void('stream').Readable;
3338
3339/**
3340 * Web / node stream conversion functions
3341 * From https://github.com/gwicke/node-web-streams
3342 */
3343
3344let nodeToWeb;
3345let webToNode;
3346
3347if (NodeReadableStream$1) {
3348
3349 /**
3350 * Convert a Node Readable Stream to a Web ReadableStream
3351 * @param {Readable} nodeStream
3352 * @returns {ReadableStream}
3353 */
3354 nodeToWeb = function(nodeStream) {
3355 return new stream.ReadableStream({
3356 start(controller) {
3357 nodeStream.pause();
3358 nodeStream.on('data', chunk => {
3359 if (NodeBuffer.isBuffer(chunk)) {
3360 chunk = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
3361 }
3362 controller.enqueue(chunk);
3363 nodeStream.pause();
3364 });
3365 nodeStream.on('end', () => controller.close());
3366 nodeStream.on('error', e => controller.error(e));
3367 },
3368 pull() {
3369 nodeStream.resume();
3370 },
3371 cancel(reason) {
3372 nodeStream.pause();
3373 if (nodeStream.cancel) {
3374 return nodeStream.cancel(reason);
3375 }
3376 }
3377 });
3378 };
3379
3380
3381 class NodeReadable extends NodeReadableStream$1 {
3382 constructor(webStream, options) {
3383 super(options);
3384 this._webStream = webStream;
3385 this._reader = stream.getReader(webStream);
3386 this._reading = false;
3387 this._doneReadingPromise = Promise.resolve();
3388 this._cancelling = false;
3389 }
3390
3391 _read(size) {
3392 if (this._reading || this._cancelling) {
3393 return;
3394 }
3395 this._reading = true;
3396 const doRead = async () => {
3397 try {
3398 while (true) {
3399 const { done, value } = await this._reader.read();
3400 if (done) {
3401 this.push(null);
3402 break;
3403 }
3404 if (!this.push(value) || this._cancelling) {
3405 this._reading = false;
3406 break;
3407 }
3408 }
3409 } catch(e) {
3410 this.emit('error', e);
3411 }
3412 };
3413 this._doneReadingPromise = doRead();
3414 }
3415
3416 async cancel(reason) {
3417 this._cancelling = true;
3418 await this._doneReadingPromise;
3419 this._reader.releaseLock();
3420 return this._webStream.cancel(reason);
3421 }
3422 }
3423
3424 /**
3425 * Convert a Web ReadableStream to a Node Readable Stream
3426 * @param {ReadableStream} webStream
3427 * @returns {Readable}
3428 */
3429 webToNode = function(webStream) {
3430 return new NodeReadable(webStream);
3431 };
3432
3433}
3434
3435const doneReadingSet = new WeakSet();
3436const externalBuffer = Symbol('externalBuffer');
3437
3438/**
3439 * A wrapper class over the native ReadableStreamDefaultReader.
3440 * This additionally implements pushing back data on the stream, which
3441 * lets us implement peeking and a host of convenience functions.
3442 * It also lets you read data other than streams, such as a Uint8Array.
3443 * @class
3444 */
3445function Reader(input) {
3446 this.stream = input;
3447 if (input[externalBuffer]) {
3448 this[externalBuffer] = input[externalBuffer].slice();
3449 }
3450 let streamType = stream.isStream(input);
3451 if (streamType === 'node') {
3452 input = stream.nodeToWeb(input);
3453 }
3454 if (streamType) {
3455 const reader = input.getReader();
3456 this._read = reader.read.bind(reader);
3457 this._releaseLock = () => {
3458 reader.closed.catch(function() {});
3459 reader.releaseLock();
3460 };
3461 return;
3462 }
3463 let doneReading = false;
3464 this._read = async () => {
3465 if (doneReading || doneReadingSet.has(input)) {
3466 return { value: undefined, done: true };
3467 }
3468 doneReading = true;
3469 return { value: input, done: false };
3470 };
3471 this._releaseLock = () => {
3472 if (doneReading) {
3473 try {
3474 doneReadingSet.add(input);
3475 } catch(e) {}
3476 }
3477 };
3478}
3479
3480/**
3481 * Read a chunk of data.
3482 * @returns {Promise<Object>} Either { done: false, value: Uint8Array | String } or { done: true, value: undefined }
3483 * @async
3484 */
3485Reader.prototype.read = async function() {
3486 if (this[externalBuffer] && this[externalBuffer].length) {
3487 const value = this[externalBuffer].shift();
3488 return { done: false, value };
3489 }
3490 return this._read();
3491};
3492
3493/**
3494 * Allow others to read the stream.
3495 */
3496Reader.prototype.releaseLock = function() {
3497 if (this[externalBuffer]) {
3498 this.stream[externalBuffer] = this[externalBuffer];
3499 }
3500 this._releaseLock();
3501};
3502
3503/**
3504 * Read up to and including the first \n character.
3505 * @returns {Promise<String|Undefined>}
3506 * @async
3507 */
3508Reader.prototype.readLine = async function() {
3509 let buffer = [];
3510 let returnVal;
3511 while (!returnVal) {
3512 let { done, value } = await this.read();
3513 value += '';
3514 if (done) {
3515 if (buffer.length) return stream.concat(buffer);
3516 return;
3517 }
3518 const lineEndIndex = value.indexOf('\n') + 1;
3519 if (lineEndIndex) {
3520 returnVal = stream.concat(buffer.concat(value.substr(0, lineEndIndex)));
3521 buffer = [];
3522 }
3523 if (lineEndIndex !== value.length) {
3524 buffer.push(value.substr(lineEndIndex));
3525 }
3526 }
3527 this.unshift(...buffer);
3528 return returnVal;
3529};
3530
3531/**
3532 * Read a single byte/character.
3533 * @returns {Promise<Number|String|Undefined>}
3534 * @async
3535 */
3536Reader.prototype.readByte = async function() {
3537 const { done, value } = await this.read();
3538 if (done) return;
3539 const byte = value[0];
3540 this.unshift(stream.slice(value, 1));
3541 return byte;
3542};
3543
3544/**
3545 * Read a specific amount of bytes/characters, unless the stream ends before that amount.
3546 * @returns {Promise<Uint8Array|String|Undefined>}
3547 * @async
3548 */
3549Reader.prototype.readBytes = async function(length) {
3550 const buffer = [];
3551 let bufferLength = 0;
3552 while (true) {
3553 const { done, value } = await this.read();
3554 if (done) {
3555 if (buffer.length) return stream.concat(buffer);
3556 return;
3557 }
3558 buffer.push(value);
3559 bufferLength += value.length;
3560 if (bufferLength >= length) {
3561 const bufferConcat = stream.concat(buffer);
3562 this.unshift(stream.slice(bufferConcat, length));
3563 return stream.slice(bufferConcat, 0, length);
3564 }
3565 }
3566};
3567
3568/**
3569 * Peek (look ahead) a specific amount of bytes/characters, unless the stream ends before that amount.
3570 * @returns {Promise<Uint8Array|String|Undefined>}
3571 * @async
3572 */
3573Reader.prototype.peekBytes = async function(length) {
3574 const bytes = await this.readBytes(length);
3575 this.unshift(bytes);
3576 return bytes;
3577};
3578
3579/**
3580 * Push data to the front of the stream.
3581 * Data must have been read in the last call to read*.
3582 * @param {...(Uint8Array|String|Undefined)} values
3583 */
3584Reader.prototype.unshift = function(...values) {
3585 if (!this[externalBuffer]) {
3586 this[externalBuffer] = [];
3587 }
3588 if (
3589 values.length === 1 && isUint8Array(values[0]) &&
3590 this[externalBuffer].length && values[0].length &&
3591 this[externalBuffer][0].byteOffset >= values[0].length
3592 ) {
3593 this[externalBuffer][0] = new Uint8Array(
3594 this[externalBuffer][0].buffer,
3595 this[externalBuffer][0].byteOffset - values[0].length,
3596 this[externalBuffer][0].byteLength + values[0].length
3597 );
3598 return;
3599 }
3600 this[externalBuffer].unshift(...values.filter(value => value && value.length));
3601};
3602
3603/**
3604 * Read the stream to the end and return its contents, concatenated by the join function (defaults to streams.concat).
3605 * @param {Function} join
3606 * @returns {Promise<Uint8array|String|Any>} the return value of join()
3607 * @async
3608 */
3609Reader.prototype.readToEnd = async function(join=stream.concat) {
3610 const result = [];
3611 while (true) {
3612 const { done, value } = await this.read();
3613 if (done) break;
3614 result.push(value);
3615 }
3616 return join(result);
3617};
3618
3619const { ReadableStream: ReadableStream$1, WritableStream: WritableStream$1, TransformStream: TransformStream$1 } = globalThis.TransformStream ? globalThis : {
3620 ReadableStream: ReadableStream,
3621 WritableStream: WritableStream,
3622 TransformStream: TransformStream
3623};
3624
3625const toPonyfillReadable = globalThis.ReadableStream &&
3626 ReadableStream$1 !== globalThis.ReadableStream &&
3627 createReadableStreamWrapper(ReadableStream$1);
3628
3629const NodeBuffer$1 = isNode && void('buffer').Buffer;
3630
3631/**
3632 * Convert data to Stream
3633 * @param {ReadableStream|Uint8array|String} input data to convert
3634 * @returns {ReadableStream} Converted data
3635 */
3636function toStream(input) {
3637 let streamType = isStream(input);
3638 if (streamType === 'node') {
3639 return nodeToWeb(input);
3640 }
3641 if (streamType === 'web' && toPonyfillReadable) {
3642 return toPonyfillReadable(input);
3643 }
3644 if (streamType) {
3645 return input;
3646 }
3647 return new ReadableStream$1({
3648 start(controller) {
3649 controller.enqueue(input);
3650 controller.close();
3651 }
3652 });
3653}
3654
3655/**
3656 * Concat a list of Uint8Arrays, Strings or Streams
3657 * The caller should not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
3658 * @param {Array<Uint8array|String|ReadableStream>} Array of Uint8Arrays/Strings/Streams to concatenate
3659 * @returns {Uint8array|String|ReadableStream} Concatenated array
3660 */
3661function concat(list) {
3662 if (list.some(isStream)) {
3663 return concatStream(list);
3664 }
3665 if (typeof list[0] === 'string') {
3666 return list.join('');
3667 }
3668 if (NodeBuffer$1 && NodeBuffer$1.isBuffer(list[0])) {
3669 return NodeBuffer$1.concat(list);
3670 }
3671 return concatUint8Array(list);
3672}
3673
3674/**
3675 * Concat a list of Streams
3676 * @param {Array<ReadableStream|Uint8array|String>} list Array of Uint8Arrays/Strings/Streams to concatenate
3677 * @returns {ReadableStream} Concatenated list
3678 */
3679function concatStream(list) {
3680 list = list.map(toStream);
3681 const transform = transformWithCancel(async function(reason) {
3682 await Promise.all(transforms.map(stream => cancel(stream, reason)));
3683 });
3684 let prev = Promise.resolve();
3685 const transforms = list.map((stream, i) => transformPair(stream, (readable, writable) => {
3686 prev = prev.then(() => pipe(readable, transform.writable, {
3687 preventClose: i !== list.length - 1
3688 }));
3689 return prev;
3690 }));
3691 return transform.readable;
3692}
3693
3694/**
3695 * Get a Reader
3696 * @param {ReadableStream|Uint8array|String} input
3697 * @returns {Reader}
3698 */
3699function getReader(input) {
3700 return new Reader(input);
3701}
3702
3703/**
3704 * Get a Writer
3705 * @param {WritableStream} input
3706 * @returns {WritableStreamDefaultWriter}
3707 */
3708function getWriter(input) {
3709 const writer = input.getWriter();
3710 const releaseLock = writer.releaseLock;
3711 writer.releaseLock = () => {
3712 writer.closed.catch(function() {});
3713 releaseLock.call(writer);
3714 };
3715 return writer;
3716}
3717
3718/**
3719 * Pipe a readable stream to a writable stream. Don't throw on input stream errors, but forward them to the output stream.
3720 * @param {ReadableStream|Uint8array|String} input
3721 * @param {WritableStream} target
3722 * @param {Object} (optional) options
3723 * @returns {Promise<undefined>} Promise indicating when piping has finished (input stream closed or errored)
3724 * @async
3725 */
3726async function pipe(input, target, options) {
3727 input = toStream(input);
3728 try {
3729 if (input[externalBuffer]) {
3730 const writer = getWriter(target);
3731 for (let i = 0; i < input[externalBuffer].length; i++) {
3732 await writer.ready;
3733 await writer.write(input[externalBuffer][i]);
3734 }
3735 writer.releaseLock();
3736 }
3737 return await input.pipeTo(target, options);
3738 } catch(e) {}
3739}
3740
3741/**
3742 * Pipe a readable stream through a transform stream.
3743 * @param {ReadableStream|Uint8array|String} input
3744 * @param {Object} (optional) options
3745 * @returns {ReadableStream} transformed stream
3746 */
3747function transformRaw(input, options) {
3748 const transformStream = new TransformStream$1(options);
3749 pipe(input, transformStream.writable);
3750 return transformStream.readable;
3751}
3752
3753/**
3754 * Create a cancelable TransformStream.
3755 * @param {Function} cancel
3756 * @returns {TransformStream}
3757 */
3758function transformWithCancel(cancel) {
3759 let pulled = false;
3760 let backpressureChangePromiseResolve;
3761 let outputController;
3762 return {
3763 readable: new ReadableStream$1({
3764 start(controller) {
3765 outputController = controller;
3766 },
3767 pull() {
3768 if (backpressureChangePromiseResolve) {
3769 backpressureChangePromiseResolve();
3770 } else {
3771 pulled = true;
3772 }
3773 },
3774 cancel
3775 }, {highWaterMark: 0}),
3776 writable: new WritableStream$1({
3777 write: async function(chunk) {
3778 outputController.enqueue(chunk);
3779 if (!pulled) {
3780 await new Promise(resolve => {
3781 backpressureChangePromiseResolve = resolve;
3782 });
3783 backpressureChangePromiseResolve = null;
3784 } else {
3785 pulled = false;
3786 }
3787 },
3788 close: outputController.close.bind(outputController),
3789 abort: outputController.error.bind(outputController)
3790 })
3791 };
3792}
3793
3794/**
3795 * Transform a stream using helper functions which are called on each chunk, and on stream close, respectively.
3796 * @param {ReadableStream|Uint8array|String} input
3797 * @param {Function} process
3798 * @param {Function} finish
3799 * @returns {ReadableStream|Uint8array|String}
3800 */
3801function transform(input, process = () => undefined, finish = () => undefined) {
3802 if (isStream(input)) {
3803 return transformRaw(input, {
3804 async transform(value, controller) {
3805 try {
3806 const result = await process(value);
3807 if (result !== undefined) controller.enqueue(result);
3808 } catch(e) {
3809 controller.error(e);
3810 }
3811 },
3812 async flush(controller) {
3813 try {
3814 const result = await finish();
3815 if (result !== undefined) controller.enqueue(result);
3816 } catch(e) {
3817 controller.error(e);
3818 }
3819 }
3820 });
3821 }
3822 const result1 = process(input);
3823 const result2 = finish();
3824 if (result1 !== undefined && result2 !== undefined) return concat([result1, result2]);
3825 return result1 !== undefined ? result1 : result2;
3826}
3827
3828/**
3829 * Transform a stream using a helper function which is passed a readable and a writable stream.
3830 * This function also maintains the possibility to cancel the input stream,
3831 * and does so on cancelation of the output stream, despite cancelation
3832 * normally being impossible when the input stream is being read from.
3833 * @param {ReadableStream|Uint8array|String} input
3834 * @param {Function} fn
3835 * @returns {ReadableStream}
3836 */
3837function transformPair(input, fn) {
3838 let incomingTransformController;
3839 const incoming = new TransformStream$1({
3840 start(controller) {
3841 incomingTransformController = controller;
3842 }
3843 });
3844
3845 const pipeDonePromise = pipe(input, incoming.writable);
3846
3847 const outgoing = transformWithCancel(async function() {
3848 incomingTransformController.error(new Error('Readable side was canceled.'));
3849 await pipeDonePromise;
3850 await new Promise(setTimeout);
3851 });
3852 fn(incoming.readable, outgoing.writable);
3853 return outgoing.readable;
3854}
3855
3856/**
3857 * Parse a stream using a helper function which is passed a Reader.
3858 * The reader additionally has a remainder() method which returns a
3859 * stream pointing to the remainder of input, and is linked to input
3860 * for cancelation.
3861 * @param {ReadableStream|Uint8array|String} input
3862 * @param {Function} fn
3863 * @returns {Any} the return value of fn()
3864 */
3865function parse(input, fn) {
3866 let returnValue;
3867 const transformed = transformPair(input, (readable, writable) => {
3868 const reader = getReader(readable);
3869 reader.remainder = () => {
3870 reader.releaseLock();
3871 pipe(readable, writable);
3872 return transformed;
3873 };
3874 returnValue = fn(reader);
3875 });
3876 return returnValue;
3877}
3878
3879/**
3880 * Tee a Stream for reading it twice. The input stream can no longer be read after tee()ing.
3881 * Reading either of the two returned streams will pull from the input stream.
3882 * The input stream will only be canceled if both of the returned streams are canceled.
3883 * @param {ReadableStream|Uint8array|String} input
3884 * @returns {Array<ReadableStream|Uint8array|String>} array containing two copies of input
3885 */
3886function tee(input) {
3887 if (isStream(input)) {
3888 const teed = toStream(input).tee();
3889 teed[0][externalBuffer] = teed[1][externalBuffer] = input[externalBuffer];
3890 return teed;
3891 }
3892 return [slice(input), slice(input)];
3893}
3894
3895/**
3896 * Clone a Stream for reading it twice. The input stream can still be read after clone()ing.
3897 * Reading from the clone will pull from the input stream.
3898 * The input stream will only be canceled if both the clone and the input stream are canceled.
3899 * @param {ReadableStream|Uint8array|String} input
3900 * @returns {ReadableStream|Uint8array|String} cloned input
3901 */
3902function clone(input) {
3903 if (isStream(input)) {
3904 const teed = tee(input);
3905 overwrite(input, teed[0]);
3906 return teed[1];
3907 }
3908 return slice(input);
3909}
3910
3911/**
3912 * Clone a Stream for reading it twice. Data will arrive at the same rate as the input stream is being read.
3913 * Reading from the clone will NOT pull from the input stream. Data only arrives when reading the input stream.
3914 * The input stream will NOT be canceled if the clone is canceled, only if the input stream are canceled.
3915 * If the input stream is canceled, the clone will be errored.
3916 * @param {ReadableStream|Uint8array|String} input
3917 * @returns {ReadableStream|Uint8array|String} cloned input
3918 */
3919function passiveClone(input) {
3920 if (isStream(input)) {
3921 return new ReadableStream$1({
3922 start(controller) {
3923 const transformed = transformPair(input, async (readable, writable) => {
3924 const reader = getReader(readable);
3925 const writer = getWriter(writable);
3926 try {
3927 while (true) {
3928 await writer.ready;
3929 const { done, value } = await reader.read();
3930 if (done) {
3931 try { controller.close(); } catch(e) {}
3932 await writer.close();
3933 return;
3934 }
3935 try { controller.enqueue(value); } catch(e) {}
3936 await writer.write(value);
3937 }
3938 } catch(e) {
3939 controller.error(e);
3940 await writer.abort(e);
3941 }
3942 });
3943 overwrite(input, transformed);
3944 }
3945 });
3946 }
3947 return slice(input);
3948}
3949
3950/**
3951 * Modify a stream object to point to a different stream object.
3952 * This is used internally by clone() and passiveClone() to provide an abstraction over tee().
3953 * @param {ReadableStream} input
3954 * @param {ReadableStream} clone
3955 */
3956function overwrite(input, clone) {
3957 // Overwrite input.getReader, input.locked, etc to point to clone
3958 Object.entries(Object.getOwnPropertyDescriptors(ReadableStream$1.prototype)).forEach(([name, descriptor]) => {
3959 if (name === 'constructor') {
3960 return;
3961 }
3962 if (descriptor.value) {
3963 descriptor.value = descriptor.value.bind(clone);
3964 } else {
3965 descriptor.get = descriptor.get.bind(clone);
3966 }
3967 Object.defineProperty(input, name, descriptor);
3968 });
3969}
3970
3971/**
3972 * Return a stream pointing to a part of the input stream.
3973 * @param {ReadableStream|Uint8array|String} input
3974 * @returns {ReadableStream|Uint8array|String} clone
3975 */
3976function slice(input, begin=0, end=Infinity) {
3977 if (isStream(input)) {
3978 if (begin >= 0 && end >= 0) {
3979 let bytesRead = 0;
3980 return transformRaw(input, {
3981 transform(value, controller) {
3982 if (bytesRead < end) {
3983 if (bytesRead + value.length >= begin) {
3984 controller.enqueue(slice(value, Math.max(begin - bytesRead, 0), end - bytesRead));
3985 }
3986 bytesRead += value.length;
3987 } else {
3988 controller.terminate();
3989 }
3990 }
3991 });
3992 }
3993 if (begin < 0 && (end < 0 || end === Infinity)) {
3994 let lastBytes = [];
3995 return transform(input, value => {
3996 if (value.length >= -begin) lastBytes = [value];
3997 else lastBytes.push(value);
3998 }, () => slice(concat(lastBytes), begin, end));
3999 }
4000 if (begin === 0 && end < 0) {
4001 let lastBytes;
4002 return transform(input, value => {
4003 const returnValue = lastBytes ? concat([lastBytes, value]) : value;
4004 if (returnValue.length >= -end) {
4005 lastBytes = slice(returnValue, end);
4006 return slice(returnValue, begin, end);
4007 } else {
4008 lastBytes = returnValue;
4009 }
4010 });
4011 }
4012 console.warn(`stream.slice(input, ${begin}, ${end}) not implemented efficiently.`);
4013 return fromAsync(async () => slice(await readToEnd(input), begin, end));
4014 }
4015 if (input[externalBuffer]) {
4016 input = concat(input[externalBuffer].concat([input]));
4017 }
4018 if (isUint8Array(input) && !(NodeBuffer$1 && NodeBuffer$1.isBuffer(input))) {
4019 if (end === Infinity) end = input.length;
4020 return input.subarray(begin, end);
4021 }
4022 return input.slice(begin, end);
4023}
4024
4025/**
4026 * Read a stream to the end and return its contents, concatenated by the concat function (defaults to concat).
4027 * @param {ReadableStream|Uint8array|String} input
4028 * @param {Function} concat
4029 * @returns {Promise<Uint8array|String|Any>} the return value of concat()
4030 * @async
4031 */
4032async function readToEnd(input, concat) {
4033 if (isStream(input)) {
4034 return getReader(input).readToEnd(concat);
4035 }
4036 return input;
4037}
4038
4039/**
4040 * Cancel a stream.
4041 * @param {ReadableStream|Uint8array|String} input
4042 * @param {Any} reason
4043 * @returns {Promise<Any>} indicates when the stream has been canceled
4044 * @async
4045 */
4046async function cancel(input, reason) {
4047 if (isStream(input) && input.cancel) {
4048 return input.cancel(reason);
4049 }
4050}
4051
4052/**
4053 * Convert an async function to a Stream. When the function returns, its return value is enqueued to the stream.
4054 * @param {Function} fn
4055 * @returns {ReadableStream}
4056 */
4057function fromAsync(fn) {
4058 return new ReadableStream$1({
4059 pull: async controller => {
4060 try {
4061 controller.enqueue(await fn());
4062 controller.close();
4063 } catch(e) {
4064 controller.error(e);
4065 }
4066 }
4067 });
4068}
4069
4070
4071var stream = { ReadableStream: ReadableStream$1, WritableStream: WritableStream$1, TransformStream: TransformStream$1, isStream, isUint8Array, toStream, concatUint8Array, concatStream, concat, getReader, getWriter, pipe, transformRaw, transform, transformPair, parse, clone, passiveClone, slice, readToEnd, cancel, fromAsync, nodeToWeb, webToNode };
4072
4073/* eslint-disable new-cap */
4074
4075/**
4076 * @fileoverview
4077 * BigInteger implementation of basic operations
4078 * that wraps the native BigInt library.
4079 * Operations are not constant time,
4080 * but we try and limit timing leakage where we can
4081 * @module biginteger/native
4082 * @private
4083 */
4084
4085/**
4086 * @private
4087 */
4088class BigInteger {
4089 /**
4090 * Get a BigInteger (input must be big endian for strings and arrays)
4091 * @param {Number|String|Uint8Array} n - Value to convert
4092 * @throws {Error} on null or undefined input
4093 */
4094 constructor(n) {
4095 if (n === undefined) {
4096 throw new Error('Invalid BigInteger input');
4097 }
4098
4099 if (n instanceof Uint8Array) {
4100 const bytes = n;
4101 const hex = new Array(bytes.length);
4102 for (let i = 0; i < bytes.length; i++) {
4103 const hexByte = bytes[i].toString(16);
4104 hex[i] = (bytes[i] <= 0xF) ? ('0' + hexByte) : hexByte;
4105 }
4106 this.value = BigInt('0x0' + hex.join(''));
4107 } else {
4108 this.value = BigInt(n);
4109 }
4110 }
4111
4112 clone() {
4113 return new BigInteger(this.value);
4114 }
4115
4116 /**
4117 * BigInteger increment in place
4118 */
4119 iinc() {
4120 this.value++;
4121 return this;
4122 }
4123
4124 /**
4125 * BigInteger increment
4126 * @returns {BigInteger} this + 1.
4127 */
4128 inc() {
4129 return this.clone().iinc();
4130 }
4131
4132 /**
4133 * BigInteger decrement in place
4134 */
4135 idec() {
4136 this.value--;
4137 return this;
4138 }
4139
4140 /**
4141 * BigInteger decrement
4142 * @returns {BigInteger} this - 1.
4143 */
4144 dec() {
4145 return this.clone().idec();
4146 }
4147
4148 /**
4149 * BigInteger addition in place
4150 * @param {BigInteger} x - Value to add
4151 */
4152 iadd(x) {
4153 this.value += x.value;
4154 return this;
4155 }
4156
4157 /**
4158 * BigInteger addition
4159 * @param {BigInteger} x - Value to add
4160 * @returns {BigInteger} this + x.
4161 */
4162 add(x) {
4163 return this.clone().iadd(x);
4164 }
4165
4166 /**
4167 * BigInteger subtraction in place
4168 * @param {BigInteger} x - Value to subtract
4169 */
4170 isub(x) {
4171 this.value -= x.value;
4172 return this;
4173 }
4174
4175 /**
4176 * BigInteger subtraction
4177 * @param {BigInteger} x - Value to subtract
4178 * @returns {BigInteger} this - x.
4179 */
4180 sub(x) {
4181 return this.clone().isub(x);
4182 }
4183
4184 /**
4185 * BigInteger multiplication in place
4186 * @param {BigInteger} x - Value to multiply
4187 */
4188 imul(x) {
4189 this.value *= x.value;
4190 return this;
4191 }
4192
4193 /**
4194 * BigInteger multiplication
4195 * @param {BigInteger} x - Value to multiply
4196 * @returns {BigInteger} this * x.
4197 */
4198 mul(x) {
4199 return this.clone().imul(x);
4200 }
4201
4202 /**
4203 * Compute value modulo m, in place
4204 * @param {BigInteger} m - Modulo
4205 */
4206 imod(m) {
4207 this.value %= m.value;
4208 if (this.isNegative()) {
4209 this.iadd(m);
4210 }
4211 return this;
4212 }
4213
4214 /**
4215 * Compute value modulo m
4216 * @param {BigInteger} m - Modulo
4217 * @returns {BigInteger} this mod m.
4218 */
4219 mod(m) {
4220 return this.clone().imod(m);
4221 }
4222
4223 /**
4224 * Compute modular exponentiation using square and multiply
4225 * @param {BigInteger} e - Exponent
4226 * @param {BigInteger} n - Modulo
4227 * @returns {BigInteger} this ** e mod n.
4228 */
4229 modExp(e, n) {
4230 if (n.isZero()) throw Error("Modulo cannot be zero");
4231 if (n.isOne()) return new BigInteger(0);
4232 if (e.isNegative()) throw Error("Unsopported negative exponent");
4233
4234 let exp = e.value;
4235 let x = this.value;
4236
4237 x %= n.value;
4238 let r = BigInt(1);
4239 while (exp > BigInt(0)) {
4240 const lsb = exp & BigInt(1);
4241 exp >>= BigInt(1); // e / 2
4242 // Always compute multiplication step, to reduce timing leakage
4243 const rx = (r * x) % n.value;
4244 // Update r only if lsb is 1 (odd exponent)
4245 r = lsb ? rx : r;
4246 x = (x * x) % n.value; // Square
4247 }
4248 return new BigInteger(r);
4249 }
4250
4251
4252 /**
4253 * Compute the inverse of this value modulo n
4254 * Note: this and and n must be relatively prime
4255 * @param {BigInteger} n - Modulo
4256 * @returns {BigInteger} x such that this*x = 1 mod n
4257 * @throws {Error} if the inverse does not exist
4258 */
4259 modInv(n) {
4260 const { gcd, x } = this._egcd(n);
4261 if (!gcd.isOne()) {
4262 throw new Error('Inverse does not exist');
4263 }
4264 return x.add(n).mod(n);
4265 }
4266
4267 /**
4268 * Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf)
4269 * Given a = this and b, compute (x, y) such that ax + by = gdc(a, b)
4270 * @param {BigInteger} b - Second operand
4271 * @returns {{ gcd, x, y: BigInteger }}
4272 */
4273 _egcd(b) {
4274 let x = BigInt(0);
4275 let y = BigInt(1);
4276 let xPrev = BigInt(1);
4277 let yPrev = BigInt(0);
4278
4279 let a = this.value;
4280 b = b.value;
4281
4282 while (b !== BigInt(0)) {
4283 const q = a / b;
4284 let tmp = x;
4285 x = xPrev - q * x;
4286 xPrev = tmp;
4287
4288 tmp = y;
4289 y = yPrev - q * y;
4290 yPrev = tmp;
4291
4292 tmp = b;
4293 b = a % b;
4294 a = tmp;
4295 }
4296
4297 return {
4298 x: new BigInteger(xPrev),
4299 y: new BigInteger(yPrev),
4300 gcd: new BigInteger(a)
4301 };
4302 }
4303
4304 /**
4305 * Compute greatest common divisor between this and n
4306 * @param {BigInteger} b - Operand
4307 * @returns {BigInteger} gcd
4308 */
4309 gcd(b) {
4310 let a = this.value;
4311 b = b.value;
4312 while (b !== BigInt(0)) {
4313 const tmp = b;
4314 b = a % b;
4315 a = tmp;
4316 }
4317 return new BigInteger(a);
4318 }
4319
4320 /**
4321 * Shift this to the left by x, in place
4322 * @param {BigInteger} x - Shift value
4323 */
4324 ileftShift(x) {
4325 this.value <<= x.value;
4326 return this;
4327 }
4328
4329 /**
4330 * Shift this to the left by x
4331 * @param {BigInteger} x - Shift value
4332 * @returns {BigInteger} this << x.
4333 */
4334 leftShift(x) {
4335 return this.clone().ileftShift(x);
4336 }
4337
4338 /**
4339 * Shift this to the right by x, in place
4340 * @param {BigInteger} x - Shift value
4341 */
4342 irightShift(x) {
4343 this.value >>= x.value;
4344 return this;
4345 }
4346
4347 /**
4348 * Shift this to the right by x
4349 * @param {BigInteger} x - Shift value
4350 * @returns {BigInteger} this >> x.
4351 */
4352 rightShift(x) {
4353 return this.clone().irightShift(x);
4354 }
4355
4356 /**
4357 * Whether this value is equal to x
4358 * @param {BigInteger} x
4359 * @returns {Boolean}
4360 */
4361 equal(x) {
4362 return this.value === x.value;
4363 }
4364
4365 /**
4366 * Whether this value is less than x
4367 * @param {BigInteger} x
4368 * @returns {Boolean}
4369 */
4370 lt(x) {
4371 return this.value < x.value;
4372 }
4373
4374 /**
4375 * Whether this value is less than or equal to x
4376 * @param {BigInteger} x
4377 * @returns {Boolean}
4378 */
4379 lte(x) {
4380 return this.value <= x.value;
4381 }
4382
4383 /**
4384 * Whether this value is greater than x
4385 * @param {BigInteger} x
4386 * @returns {Boolean}
4387 */
4388 gt(x) {
4389 return this.value > x.value;
4390 }
4391
4392 /**
4393 * Whether this value is greater than or equal to x
4394 * @param {BigInteger} x
4395 * @returns {Boolean}
4396 */
4397 gte(x) {
4398 return this.value >= x.value;
4399 }
4400
4401 isZero() {
4402 return this.value === BigInt(0);
4403 }
4404
4405 isOne() {
4406 return this.value === BigInt(1);
4407 }
4408
4409 isNegative() {
4410 return this.value < BigInt(0);
4411 }
4412
4413 isEven() {
4414 return !(this.value & BigInt(1));
4415 }
4416
4417 abs() {
4418 const res = this.clone();
4419 if (this.isNegative()) {
4420 res.value = -res.value;
4421 }
4422 return res;
4423 }
4424
4425 /**
4426 * Get this value as a string
4427 * @returns {String} this value.
4428 */
4429 toString() {
4430 return this.value.toString();
4431 }
4432
4433 /**
4434 * Get this value as an exact Number (max 53 bits)
4435 * Fails if this value is too large
4436 * @returns {Number}
4437 */
4438 toNumber() {
4439 const number = Number(this.value);
4440 if (number > Number.MAX_SAFE_INTEGER) {
4441 // We throw and error to conform with the bn.js implementation
4442 throw new Error('Number can only safely store up to 53 bits');
4443 }
4444 return number;
4445 }
4446
4447 /**
4448 * Get value of i-th bit
4449 * @param {Number} i - Bit index
4450 * @returns {Number} Bit value.
4451 */
4452 getBit(i) {
4453 const bit = (this.value >> BigInt(i)) & BigInt(1);
4454 return (bit === BigInt(0)) ? 0 : 1;
4455 }
4456
4457 /**
4458 * Compute bit length
4459 * @returns {Number} Bit length.
4460 */
4461 bitLength() {
4462 const zero = new BigInteger(0);
4463 const one = new BigInteger(1);
4464 const negOne = new BigInteger(-1);
4465
4466 // -1n >> -1n is -1n
4467 // 1n >> 1n is 0n
4468 const target = this.isNegative() ? negOne : zero;
4469 let bitlen = 1;
4470 const tmp = this.clone();
4471 while (!tmp.irightShift(one).equal(target)) {
4472 bitlen++;
4473 }
4474 return bitlen;
4475 }
4476
4477 /**
4478 * Compute byte length
4479 * @returns {Number} Byte length.
4480 */
4481 byteLength() {
4482 const zero = new BigInteger(0);
4483 const negOne = new BigInteger(-1);
4484
4485 const target = this.isNegative() ? negOne : zero;
4486 const eight = new BigInteger(8);
4487 let len = 1;
4488 const tmp = this.clone();
4489 while (!tmp.irightShift(eight).equal(target)) {
4490 len++;
4491 }
4492 return len;
4493 }
4494
4495 /**
4496 * Get Uint8Array representation of this number
4497 * @param {String} endian - Endianess of output array (defaults to 'be')
4498 * @param {Number} length - Of output array
4499 * @returns {Uint8Array}
4500 */
4501 toUint8Array(endian = 'be', length) {
4502 // we get and parse the hex string (https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/)
4503 // this is faster than shift+mod iterations
4504 let hex = this.value.toString(16);
4505 if (hex.length % 2 === 1) {
4506 hex = '0' + hex;
4507 }
4508
4509 const rawLength = hex.length / 2;
4510 const bytes = new Uint8Array(length || rawLength);
4511 // parse hex
4512 const offset = length ? (length - rawLength) : 0;
4513 let i = 0;
4514 while (i < rawLength) {
4515 bytes[i + offset] = parseInt(hex.slice(2 * i, 2 * i + 2), 16);
4516 i++;
4517 }
4518
4519 if (endian !== 'be') {
4520 bytes.reverse();
4521 }
4522
4523 return bytes;
4524 }
4525}
4526
4527async function getBigInteger() {
4528 if (util.detectBigInt()) {
4529 return BigInteger;
4530 } else {
4531 const { default: BigInteger } = await import('./bn.interface.mjs');
4532 return BigInteger;
4533 }
4534}
4535
4536// GPG4Browsers - An OpenPGP implementation in javascript
4537
4538const debugMode = globalThis.process && globalThis.process.env.NODE_ENV === 'development';
4539
4540const util = {
4541 isString: function(data) {
4542 return typeof data === 'string' || String.prototype.isPrototypeOf(data);
4543 },
4544
4545 isArray: function(data) {
4546 return Array.prototype.isPrototypeOf(data);
4547 },
4548
4549 isBigInteger: function(data) {
4550 return data !== null && typeof data === 'object' && data.value &&
4551 // eslint-disable-next-line valid-typeof
4552 (typeof data.value === 'bigint' || this.isBN(data.value));
4553 },
4554
4555 isBN: function(data) {
4556 return data !== null && typeof data === 'object' &&
4557 (data.constructor.name === 'BN' ||
4558 (data.constructor.wordSize === 26 && Array.isArray(data.words))); // taken from BN.isBN()
4559 },
4560
4561 isUint8Array: stream.isUint8Array,
4562
4563 isStream: stream.isStream,
4564
4565 /**
4566 * Convert MessagePorts back to ReadableStreams
4567 * @param {Object} obj
4568 * @returns {Object}
4569 */
4570 restoreStreams: function(obj, streaming) {
4571 if (Object.prototype.toString.call(obj) === '[object MessagePort]') {
4572 return new (streaming === 'web' ? globalThis.ReadableStream : stream.ReadableStream)({
4573 pull(controller) {
4574 return new Promise(resolve => {
4575 obj.onmessage = evt => {
4576 const { done, value, error } = evt.data;
4577 if (error) {
4578 controller.error(new Error(error));
4579 } else if (!done) {
4580 controller.enqueue(value);
4581 } else {
4582 controller.close();
4583 }
4584 resolve();
4585 };
4586 obj.postMessage({ action: 'read' });
4587 });
4588 },
4589 cancel() {
4590 return new Promise(resolve => {
4591 obj.onmessage = resolve;
4592 obj.postMessage({ action: 'cancel' });
4593 });
4594 }
4595 }, { highWaterMark: 0 });
4596 }
4597 if (Object.prototype.isPrototypeOf(obj) && !Uint8Array.prototype.isPrototypeOf(obj)) {
4598 Object.entries(obj).forEach(([key, value]) => { // recursively search all children
4599 obj[key] = util.restoreStreams(value, streaming);
4600 });
4601 }
4602 return obj;
4603 },
4604
4605 readNumber: function (bytes) {
4606 let n = 0;
4607 for (let i = 0; i < bytes.length; i++) {
4608 n += (256 ** i) * bytes[bytes.length - 1 - i];
4609 }
4610 return n;
4611 },
4612
4613 writeNumber: function (n, bytes) {
4614 const b = new Uint8Array(bytes);
4615 for (let i = 0; i < bytes; i++) {
4616 b[i] = (n >> (8 * (bytes - i - 1))) & 0xFF;
4617 }
4618
4619 return b;
4620 },
4621
4622 readDate: function (bytes) {
4623 const n = util.readNumber(bytes);
4624 const d = new Date(n * 1000);
4625 return d;
4626 },
4627
4628 writeDate: function (time) {
4629 const numeric = Math.floor(time.getTime() / 1000);
4630
4631 return util.writeNumber(numeric, 4);
4632 },
4633
4634 normalizeDate: function (time = Date.now()) {
4635 return time === null || time === Infinity ? time : new Date(Math.floor(+time / 1000) * 1000);
4636 },
4637
4638 /**
4639 * Create hex string from a binary
4640 * @param {String} str - String to convert
4641 * @returns {String} String containing the hexadecimal values.
4642 */
4643 strToHex: function (str) {
4644 if (str === null) {
4645 return "";
4646 }
4647 const r = [];
4648 const e = str.length;
4649 let c = 0;
4650 let h;
4651 while (c < e) {
4652 h = str.charCodeAt(c++).toString(16);
4653 while (h.length < 2) {
4654 h = "0" + h;
4655 }
4656 r.push("" + h);
4657 }
4658 return r.join('');
4659 },
4660
4661 /**
4662 * Create binary string from a hex encoded string
4663 * @param {String} str - Hex string to convert
4664 * @returns {String}
4665 */
4666 hexToStr: function (hex) {
4667 let str = '';
4668 for (let i = 0; i < hex.length; i += 2) {
4669 str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
4670 }
4671 return str;
4672 },
4673
4674 /**
4675 * Read one MPI from bytes in input
4676 * @param {Uint8Array} bytes - Input data to parse
4677 * @returns {Uint8Array} Parsed MPI.
4678 */
4679 readMPI: function (bytes) {
4680 const bits = (bytes[0] << 8) | bytes[1];
4681 const bytelen = (bits + 7) >>> 3;
4682 return bytes.subarray(2, 2 + bytelen);
4683 },
4684
4685 /**
4686 * Left-pad Uint8Array to length by adding 0x0 bytes
4687 * @param {Uint8Array} bytes - Data to pad
4688 * @param {Number} length - Padded length
4689 * @returns {Uint8Array} Padded bytes.
4690 */
4691 leftPad(bytes, length) {
4692 const padded = new Uint8Array(length);
4693 const offset = length - bytes.length;
4694 padded.set(bytes, offset);
4695 return padded;
4696 },
4697
4698 /**
4699 * Convert a Uint8Array to an MPI-formatted Uint8Array.
4700 * @param {Uint8Array} bin - An array of 8-bit integers to convert
4701 * @returns {Uint8Array} MPI-formatted Uint8Array.
4702 */
4703 uint8ArrayToMpi: function (bin) {
4704 let i; // index of leading non-zero byte
4705 for (i = 0; i < bin.length; i++) if (bin[i] !== 0) break;
4706 if (i === bin.length) {
4707 throw new Error('Zero MPI');
4708 }
4709 const stripped = bin.subarray(i);
4710 const size = (stripped.length - 1) * 8 + util.nbits(stripped[0]);
4711 const prefix = Uint8Array.from([(size & 0xFF00) >> 8, size & 0xFF]);
4712 return util.concatUint8Array([prefix, stripped]);
4713 },
4714
4715 /**
4716 * Convert a hex string to an array of 8-bit integers
4717 * @param {String} hex - A hex string to convert
4718 * @returns {Uint8Array} An array of 8-bit integers.
4719 */
4720 hexToUint8Array: function (hex) {
4721 const result = new Uint8Array(hex.length >> 1);
4722 for (let k = 0; k < hex.length >> 1; k++) {
4723 result[k] = parseInt(hex.substr(k << 1, 2), 16);
4724 }
4725 return result;
4726 },
4727
4728 /**
4729 * Convert an array of 8-bit integers to a hex string
4730 * @param {Uint8Array} bytes - Array of 8-bit integers to convert
4731 * @returns {String} Hexadecimal representation of the array.
4732 */
4733 uint8ArrayToHex: function (bytes) {
4734 const r = [];
4735 const e = bytes.length;
4736 let c = 0;
4737 let h;
4738 while (c < e) {
4739 h = bytes[c++].toString(16);
4740 while (h.length < 2) {
4741 h = "0" + h;
4742 }
4743 r.push("" + h);
4744 }
4745 return r.join('');
4746 },
4747
4748 /**
4749 * Convert a string to an array of 8-bit integers
4750 * @param {String} str - String to convert
4751 * @returns {Uint8Array} An array of 8-bit integers.
4752 */
4753 strToUint8Array: function (str) {
4754 return stream.transform(str, str => {
4755 if (!util.isString(str)) {
4756 throw new Error('strToUint8Array: Data must be in the form of a string');
4757 }
4758
4759 const result = new Uint8Array(str.length);
4760 for (let i = 0; i < str.length; i++) {
4761 result[i] = str.charCodeAt(i);
4762 }
4763 return result;
4764 });
4765 },
4766
4767 /**
4768 * Convert an array of 8-bit integers to a string
4769 * @param {Uint8Array} bytes - An array of 8-bit integers to convert
4770 * @returns {String} String representation of the array.
4771 */
4772 uint8ArrayToStr: function (bytes) {
4773 bytes = new Uint8Array(bytes);
4774 const result = [];
4775 const bs = 1 << 14;
4776 const j = bytes.length;
4777
4778 for (let i = 0; i < j; i += bs) {
4779 result.push(String.fromCharCode.apply(String, bytes.subarray(i, i + bs < j ? i + bs : j)));
4780 }
4781 return result.join('');
4782 },
4783
4784 /**
4785 * Convert a native javascript string to a Uint8Array of utf8 bytes
4786 * @param {String|ReadableStream} str - The string to convert
4787 * @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
4788 */
4789 encodeUtf8: function (str) {
4790 const encoder = new TextEncoder('utf-8');
4791 // eslint-disable-next-line no-inner-declarations
4792 function process(value, lastChunk = false) {
4793 return encoder.encode(value, { stream: !lastChunk });
4794 }
4795 return stream.transform(str, process, () => process('', true));
4796 },
4797
4798 /**
4799 * Convert a Uint8Array of utf8 bytes to a native javascript string
4800 * @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
4801 * @returns {String|ReadableStream} A native javascript string.
4802 */
4803 decodeUtf8: function (utf8) {
4804 const decoder = new TextDecoder('utf-8');
4805 // eslint-disable-next-line no-inner-declarations
4806 function process(value, lastChunk = false) {
4807 return decoder.decode(value, { stream: !lastChunk });
4808 }
4809 return stream.transform(utf8, process, () => process(new Uint8Array(), true));
4810 },
4811
4812 /**
4813 * Concat a list of Uint8Arrays, Strings or Streams
4814 * The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
4815 * @param {Array<Uint8Array|String|ReadableStream>} Array - Of Uint8Arrays/Strings/Streams to concatenate
4816 * @returns {Uint8Array|String|ReadableStream} Concatenated array.
4817 */
4818 concat: stream.concat,
4819
4820 /**
4821 * Concat Uint8Arrays
4822 * @param {Array<Uint8Array>} Array - Of Uint8Arrays to concatenate
4823 * @returns {Uint8Array} Concatenated array.
4824 */
4825 concatUint8Array: stream.concatUint8Array,
4826
4827 /**
4828 * Check Uint8Array equality
4829 * @param {Uint8Array} array1 - First array
4830 * @param {Uint8Array} array2 - Second array
4831 * @returns {Boolean} Equality.
4832 */
4833 equalsUint8Array: function (array1, array2) {
4834 if (!util.isUint8Array(array1) || !util.isUint8Array(array2)) {
4835 throw new Error('Data must be in the form of a Uint8Array');
4836 }
4837
4838 if (array1.length !== array2.length) {
4839 return false;
4840 }
4841
4842 for (let i = 0; i < array1.length; i++) {
4843 if (array1[i] !== array2[i]) {
4844 return false;
4845 }
4846 }
4847 return true;
4848 },
4849
4850 /**
4851 * Calculates a 16bit sum of a Uint8Array by adding each character
4852 * codes modulus 65535
4853 * @param {Uint8Array} Uint8Array - To create a sum of
4854 * @returns {Uint8Array} 2 bytes containing the sum of all charcodes % 65535.
4855 */
4856 writeChecksum: function (text) {
4857 let s = 0;
4858 for (let i = 0; i < text.length; i++) {
4859 s = (s + text[i]) & 0xFFFF;
4860 }
4861 return util.writeNumber(s, 2);
4862 },
4863
4864 /**
4865 * Helper function to print a debug message. Debug
4866 * messages are only printed if
4867 * @param {String} str - String of the debug message
4868 */
4869 printDebug: function (str) {
4870 if (debugMode) {
4871 console.log(str);
4872 }
4873 },
4874
4875 /**
4876 * Helper function to print a debug message. Debug
4877 * messages are only printed if
4878 * Different than print_debug because will call Uint8ArrayToHex iff necessary.
4879 * @param {String} str - String of the debug message
4880 */
4881 printDebugHexArrayDump: function (str, arrToHex) {
4882 if (debugMode) {
4883 str += ': ' + util.uint8ArrayToHex(arrToHex);
4884 console.log(str);
4885 }
4886 },
4887
4888 /**
4889 * Helper function to print a debug message. Debug
4890 * messages are only printed if
4891 * Different than print_debug because will call strToHex iff necessary.
4892 * @param {String} str - String of the debug message
4893 */
4894 printDebugHexStrDump: function (str, strToHex) {
4895 if (debugMode) {
4896 str += util.strToHex(strToHex);
4897 console.log(str);
4898 }
4899 },
4900
4901 /**
4902 * Helper function to print a debug error. Debug
4903 * messages are only printed if
4904 * @param {String} str - String of the debug message
4905 */
4906 printDebugError: function (error) {
4907 if (debugMode) {
4908 console.error(error);
4909 }
4910 },
4911
4912 /**
4913 * Read a stream to the end and print it to the console when it's closed.
4914 * @param {String} str - String of the debug message
4915 * @param {ReadableStream|Uint8array|String} input - Stream to print
4916 * @param {Function} concat - Function to concatenate chunks of the stream (defaults to util.concat).
4917 */
4918 printEntireStream: function (str, input, concat) {
4919 stream.readToEnd(stream.clone(input), concat).then(result => {
4920 console.log(str + ': ', result);
4921 });
4922 },
4923
4924 // returns bit length of the integer x
4925 nbits: function (x) {
4926 let r = 1;
4927 let t = x >>> 16;
4928 if (t !== 0) {
4929 x = t;
4930 r += 16;
4931 }
4932 t = x >> 8;
4933 if (t !== 0) {
4934 x = t;
4935 r += 8;
4936 }
4937 t = x >> 4;
4938 if (t !== 0) {
4939 x = t;
4940 r += 4;
4941 }
4942 t = x >> 2;
4943 if (t !== 0) {
4944 x = t;
4945 r += 2;
4946 }
4947 t = x >> 1;
4948 if (t !== 0) {
4949 x = t;
4950 r += 1;
4951 }
4952 return r;
4953 },
4954
4955 /**
4956 * If S[1] == 0, then double(S) == (S[2..128] || 0);
4957 * otherwise, double(S) == (S[2..128] || 0) xor
4958 * (zeros(120) || 10000111).
4959 *
4960 * Both OCB and EAX (through CMAC) require this function to be constant-time.
4961 *
4962 * @param {Uint8Array} data
4963 */
4964 double: function(data) {
4965 const double_var = new Uint8Array(data.length);
4966 const last = data.length - 1;
4967 for (let i = 0; i < last; i++) {
4968 double_var[i] = (data[i] << 1) ^ (data[i + 1] >> 7);
4969 }
4970 double_var[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87);
4971 return double_var;
4972 },
4973
4974 /**
4975 * Shift a Uint8Array to the right by n bits
4976 * @param {Uint8Array} array - The array to shift
4977 * @param {Integer} bits - Amount of bits to shift (MUST be smaller
4978 * than 8)
4979 * @returns {String} Resulting array.
4980 */
4981 shiftRight: function (array, bits) {
4982 if (bits) {
4983 for (let i = array.length - 1; i >= 0; i--) {
4984 array[i] >>= bits;
4985 if (i > 0) {
4986 array[i] |= (array[i - 1] << (8 - bits));
4987 }
4988 }
4989 }
4990 return array;
4991 },
4992
4993 /**
4994 * Get native Web Cryptography api, only the current version of the spec.
4995 * @returns {Object} The SubtleCrypto api or 'undefined'.
4996 */
4997 getWebCrypto: function() {
4998 return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle;
4999 },
5000
5001 /**
5002 * Detect Node.js runtime.
5003 */
5004 detectNode: function() {
5005 return typeof globalThis.process === 'object' &&
5006 typeof globalThis.process.versions === 'object';
5007 },
5008
5009 /**
5010 * Detect native BigInt support
5011 */
5012 detectBigInt: () => typeof BigInt !== 'undefined',
5013
5014 /**
5015 * Get BigInteger class
5016 * It wraps the native BigInt type if it's available
5017 * Otherwise it relies on bn.js
5018 * @returns {BigInteger}
5019 * @async
5020 */
5021 getBigInteger,
5022
5023 /**
5024 * Get native Node.js crypto api.
5025 * @returns {Object} The crypto module or 'undefined'.
5026 */
5027 getNodeCrypto: function() {
5028 return void('crypto');
5029 },
5030
5031 getNodeZlib: function() {
5032 return void('zlib');
5033 },
5034
5035 /**
5036 * Get native Node.js Buffer constructor. This should be used since
5037 * Buffer is not available under browserify.
5038 * @returns {Function} The Buffer constructor or 'undefined'.
5039 */
5040 getNodeBuffer: function() {
5041 return ({}).Buffer;
5042 },
5043
5044 getNodeStream: function() {
5045 return ({}).Readable;
5046 },
5047
5048 getHardwareConcurrency: function() {
5049 if (util.detectNode()) {
5050 const os = void('os');
5051 return os.cpus().length;
5052 }
5053
5054 return navigator.hardwareConcurrency || 1;
5055 },
5056
5057 isEmailAddress: function(data) {
5058 if (!util.isString(data)) {
5059 return false;
5060 }
5061 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]+)))$/;
5062 return re.test(data);
5063 },
5064
5065 /**
5066 * Normalize line endings to <CR><LF>
5067 * Support any encoding where CR=0x0D, LF=0x0A
5068 */
5069 canonicalizeEOL: function(data) {
5070 const CR = 13;
5071 const LF = 10;
5072 let carryOverCR = false;
5073
5074 return stream.transform(data, bytes => {
5075 if (carryOverCR) {
5076 bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
5077 }
5078
5079 if (bytes[bytes.length - 1] === CR) {
5080 carryOverCR = true;
5081 bytes = bytes.subarray(0, -1);
5082 } else {
5083 carryOverCR = false;
5084 }
5085
5086 let index;
5087 const indices = [];
5088 for (let i = 0; ; i = index) {
5089 index = bytes.indexOf(LF, i) + 1;
5090 if (index) {
5091 if (bytes[index - 2] !== CR) indices.push(index);
5092 } else {
5093 break;
5094 }
5095 }
5096 if (!indices.length) {
5097 return bytes;
5098 }
5099
5100 const normalized = new Uint8Array(bytes.length + indices.length);
5101 let j = 0;
5102 for (let i = 0; i < indices.length; i++) {
5103 const sub = bytes.subarray(indices[i - 1] || 0, indices[i]);
5104 normalized.set(sub, j);
5105 j += sub.length;
5106 normalized[j - 1] = CR;
5107 normalized[j] = LF;
5108 j++;
5109 }
5110 normalized.set(bytes.subarray(indices[indices.length - 1] || 0), j);
5111 return normalized;
5112 }, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
5113 },
5114
5115 /**
5116 * Convert line endings from canonicalized <CR><LF> to native <LF>
5117 * Support any encoding where CR=0x0D, LF=0x0A
5118 */
5119 nativeEOL: function(data) {
5120 const CR = 13;
5121 const LF = 10;
5122 let carryOverCR = false;
5123
5124 return stream.transform(data, bytes => {
5125 if (carryOverCR && bytes[0] !== LF) {
5126 bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
5127 } else {
5128 bytes = new Uint8Array(bytes); // Don't mutate passed bytes
5129 }
5130
5131 if (bytes[bytes.length - 1] === CR) {
5132 carryOverCR = true;
5133 bytes = bytes.subarray(0, -1);
5134 } else {
5135 carryOverCR = false;
5136 }
5137
5138 let index;
5139 let j = 0;
5140 for (let i = 0; i !== bytes.length; i = index) {
5141 index = bytes.indexOf(CR, i) + 1;
5142 if (!index) index = bytes.length;
5143 const last = index - (bytes[index] === LF ? 1 : 0);
5144 if (i) bytes.copyWithin(j, i, last);
5145 j += last - i;
5146 }
5147 return bytes.subarray(0, j);
5148 }, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
5149 },
5150
5151 /**
5152 * Remove trailing spaces and tabs from each line
5153 */
5154 removeTrailingSpaces: function(text) {
5155 return text.split('\n').map(line => {
5156 let i = line.length - 1;
5157 for (; i >= 0 && (line[i] === ' ' || line[i] === '\t'); i--);
5158 return line.substr(0, i + 1);
5159 }).join('\n');
5160 },
5161
5162 wrapError: function(message, error) {
5163 if (!error) {
5164 return new Error(message);
5165 }
5166
5167 // update error message
5168 try {
5169 error.message = message + ': ' + error.message;
5170 } catch (e) {}
5171
5172 return error;
5173 }
5174};
5175
5176/* OpenPGP radix-64/base64 string encoding/decoding
5177 * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
5178 * version 1.0, check www.haneWIN.de for the latest version
5179 *
5180 * This software is provided as-is, without express or implied warranty.
5181 * Permission to use, copy, modify, distribute or sell this software, with or
5182 * without fee, for any purpose and by any individual or organization, is hereby
5183 * granted, provided that the above copyright notice and this paragraph appear
5184 * in all copies. Distribution as a part of an application or binary must
5185 * include the above copyright notice in the documentation and/or other materials
5186 * provided with the application or distribution.
5187 */
5188
5189const Buffer = util.getNodeBuffer();
5190
5191let encodeChunk;
5192let decodeChunk;
5193if (Buffer) {
5194 encodeChunk = buf => Buffer.from(buf).toString('base64');
5195 decodeChunk = str => {
5196 const b = Buffer.from(str, 'base64');
5197 return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
5198 };
5199} else {
5200 encodeChunk = buf => btoa(util.uint8ArrayToStr(buf));
5201 decodeChunk = str => util.strToUint8Array(atob(str));
5202}
5203
5204/**
5205 * Convert binary array to radix-64
5206 * @param {Uint8Array | ReadableStream<Uint8Array>} data - Uint8Array to convert
5207 * @returns {String | ReadableStream<String>} Radix-64 version of input string.
5208 * @static
5209 */
5210function encode(data) {
5211 let buf = new Uint8Array();
5212 return stream.transform(data, value => {
5213 buf = util.concatUint8Array([buf, value]);
5214 const r = [];
5215 const bytesPerLine = 45; // 60 chars per line * (3 bytes / 4 chars of base64).
5216 const lines = Math.floor(buf.length / bytesPerLine);
5217 const bytes = lines * bytesPerLine;
5218 const encoded = encodeChunk(buf.subarray(0, bytes));
5219 for (let i = 0; i < lines; i++) {
5220 r.push(encoded.substr(i * 60, 60));
5221 r.push('\n');
5222 }
5223 buf = buf.subarray(bytes);
5224 return r.join('');
5225 }, () => (buf.length ? encodeChunk(buf) + '\n' : ''));
5226}
5227
5228/**
5229 * Convert radix-64 to binary array
5230 * @param {String | ReadableStream<String>} data - Radix-64 string to convert
5231 * @returns {Uint8Array | ReadableStream<Uint8Array>} Binary array version of input string.
5232 * @static
5233 */
5234function decode(data) {
5235 let buf = '';
5236 return stream.transform(data, value => {
5237 buf += value;
5238
5239 // Count how many whitespace characters there are in buf
5240 let spaces = 0;
5241 const spacechars = [' ', '\t', '\r', '\n'];
5242 for (let i = 0; i < spacechars.length; i++) {
5243 const spacechar = spacechars[i];
5244 for (let pos = buf.indexOf(spacechar); pos !== -1; pos = buf.indexOf(spacechar, pos + 1)) {
5245 spaces++;
5246 }
5247 }
5248
5249 // Backtrack until we have 4n non-whitespace characters
5250 // that we can safely base64-decode
5251 let length = buf.length;
5252 for (; length > 0 && (length - spaces) % 4 !== 0; length--) {
5253 if (spacechars.includes(buf[length])) spaces--;
5254 }
5255
5256 const decoded = decodeChunk(buf.substr(0, length));
5257 buf = buf.substr(length);
5258 return decoded;
5259 }, () => decodeChunk(buf));
5260}
5261
5262/**
5263 * Convert a Base-64 encoded string an array of 8-bit integer
5264 *
5265 * Note: accepts both Radix-64 and URL-safe strings
5266 * @param {String} base64 - Base-64 encoded string to convert
5267 * @returns {Uint8Array} An array of 8-bit integers.
5268 */
5269function b64ToUint8Array(base64) {
5270 return decode(base64.replace(/-/g, '+').replace(/_/g, '/'));
5271}
5272
5273/**
5274 * Convert an array of 8-bit integer to a Base-64 encoded string
5275 * @param {Uint8Array} bytes - An array of 8-bit integers to convert
5276 * @param {bool} url - If true, output is URL-safe
5277 * @returns {String} Base-64 encoded string.
5278 */
5279function uint8ArrayToB64(bytes, url) {
5280 let encoded = encode(bytes).replace(/[\r\n]/g, '');
5281 if (url) {
5282 encoded = encoded.replace(/[+]/g, '-').replace(/[/]/g, '_').replace(/[=]/g, '');
5283 }
5284 return encoded;
5285}
5286
5287/**
5288 * @module enums
5289 */
5290
5291const byValue = Symbol('byValue');
5292
5293var enums = {
5294
5295 /** Maps curve names under various standards to one
5296 * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
5297 * @enum {String}
5298 * @readonly
5299 */
5300 curve: {
5301 /** NIST P-256 Curve */
5302 "p256": "p256",
5303 "P-256": "p256",
5304 "secp256r1": "p256",
5305 "prime256v1": "p256",
5306 "1.2.840.10045.3.1.7": "p256",
5307 "2a8648ce3d030107": "p256",
5308 "2A8648CE3D030107": "p256",
5309
5310 /** NIST P-384 Curve */
5311 "p384": "p384",
5312 "P-384": "p384",
5313 "secp384r1": "p384",
5314 "1.3.132.0.34": "p384",
5315 "2b81040022": "p384",
5316 "2B81040022": "p384",
5317
5318 /** NIST P-521 Curve */
5319 "p521": "p521",
5320 "P-521": "p521",
5321 "secp521r1": "p521",
5322 "1.3.132.0.35": "p521",
5323 "2b81040023": "p521",
5324 "2B81040023": "p521",
5325
5326 /** SECG SECP256k1 Curve */
5327 "secp256k1": "secp256k1",
5328 "1.3.132.0.10": "secp256k1",
5329 "2b8104000a": "secp256k1",
5330 "2B8104000A": "secp256k1",
5331
5332 /** Ed25519 */
5333 "ED25519": "ed25519",
5334 "ed25519": "ed25519",
5335 "Ed25519": "ed25519",
5336 "1.3.6.1.4.1.11591.15.1": "ed25519",
5337 "2b06010401da470f01": "ed25519",
5338 "2B06010401DA470F01": "ed25519",
5339
5340 /** Curve25519 */
5341 "X25519": "curve25519",
5342 "cv25519": "curve25519",
5343 "curve25519": "curve25519",
5344 "Curve25519": "curve25519",
5345 "1.3.6.1.4.1.3029.1.5.1": "curve25519",
5346 "2b060104019755010501": "curve25519",
5347 "2B060104019755010501": "curve25519",
5348
5349 /** BrainpoolP256r1 Curve */
5350 "brainpoolP256r1": "brainpoolP256r1",
5351 "1.3.36.3.3.2.8.1.1.7": "brainpoolP256r1",
5352 "2b2403030208010107": "brainpoolP256r1",
5353 "2B2403030208010107": "brainpoolP256r1",
5354
5355 /** BrainpoolP384r1 Curve */
5356 "brainpoolP384r1": "brainpoolP384r1",
5357 "1.3.36.3.3.2.8.1.1.11": "brainpoolP384r1",
5358 "2b240303020801010b": "brainpoolP384r1",
5359 "2B240303020801010B": "brainpoolP384r1",
5360
5361 /** BrainpoolP512r1 Curve */
5362 "brainpoolP512r1": "brainpoolP512r1",
5363 "1.3.36.3.3.2.8.1.1.13": "brainpoolP512r1",
5364 "2b240303020801010d": "brainpoolP512r1",
5365 "2B240303020801010D": "brainpoolP512r1"
5366 },
5367
5368 /** A string to key specifier type
5369 * @enum {Integer}
5370 * @readonly
5371 */
5372 s2k: {
5373 simple: 0,
5374 salted: 1,
5375 iterated: 3,
5376 gnu: 101
5377 },
5378
5379 /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.1|RFC4880bis-04, section 9.1}
5380 * @enum {Integer}
5381 * @readonly
5382 */
5383 publicKey: {
5384 /** RSA (Encrypt or Sign) [HAC] */
5385 rsaEncryptSign: 1,
5386 /** RSA (Encrypt only) [HAC] */
5387 rsaEncrypt: 2,
5388 /** RSA (Sign only) [HAC] */
5389 rsaSign: 3,
5390 /** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
5391 elgamal: 16,
5392 /** DSA (Sign only) [FIPS186] [HAC] */
5393 dsa: 17,
5394 /** ECDH (Encrypt only) [RFC6637] */
5395 ecdh: 18,
5396 /** ECDSA (Sign only) [RFC6637] */
5397 ecdsa: 19,
5398 /** EdDSA (Sign only)
5399 * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
5400 eddsa: 22,
5401 /** Reserved for AEDH */
5402 aedh: 23,
5403 /** Reserved for AEDSA */
5404 aedsa: 24
5405 },
5406
5407 /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
5408 * @enum {Integer}
5409 * @readonly
5410 */
5411 symmetric: {
5412 plaintext: 0,
5413 /** Not implemented! */
5414 idea: 1,
5415 tripledes: 2,
5416 cast5: 3,
5417 blowfish: 4,
5418 aes128: 7,
5419 aes192: 8,
5420 aes256: 9,
5421 twofish: 10
5422 },
5423
5424 /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
5425 * @enum {Integer}
5426 * @readonly
5427 */
5428 compression: {
5429 uncompressed: 0,
5430 /** RFC1951 */
5431 zip: 1,
5432 /** RFC1950 */
5433 zlib: 2,
5434 bzip2: 3
5435 },
5436
5437 /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
5438 * @enum {Integer}
5439 * @readonly
5440 */
5441 hash: {
5442 md5: 1,
5443 sha1: 2,
5444 ripemd: 3,
5445 sha256: 8,
5446 sha384: 9,
5447 sha512: 10,
5448 sha224: 11
5449 },
5450
5451 /** A list of hash names as accepted by webCrypto functions.
5452 * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
5453 * @enum {String}
5454 */
5455 webHash: {
5456 'SHA-1': 2,
5457 'SHA-256': 8,
5458 'SHA-384': 9,
5459 'SHA-512': 10
5460 },
5461
5462 /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
5463 * @enum {Integer}
5464 * @readonly
5465 */
5466 aead: {
5467 eax: 1,
5468 ocb: 2,
5469 experimentalGcm: 100 // Private algorithm
5470 },
5471
5472 /** A list of packet types and numeric tags associated with them.
5473 * @enum {Integer}
5474 * @readonly
5475 */
5476 packet: {
5477 publicKeyEncryptedSessionKey: 1,
5478 signature: 2,
5479 symEncryptedSessionKey: 3,
5480 onePassSignature: 4,
5481 secretKey: 5,
5482 publicKey: 6,
5483 secretSubkey: 7,
5484 compressedData: 8,
5485 symmetricallyEncryptedData: 9,
5486 marker: 10,
5487 literalData: 11,
5488 trust: 12,
5489 userID: 13,
5490 publicSubkey: 14,
5491 userAttribute: 17,
5492 symEncryptedIntegrityProtectedData: 18,
5493 modificationDetectionCode: 19,
5494 AEADEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
5495 },
5496
5497 /** Data types in the literal packet
5498 * @enum {Integer}
5499 * @readonly
5500 */
5501 literal: {
5502 /** Binary data 'b' */
5503 binary: 'b'.charCodeAt(),
5504 /** Text data 't' */
5505 text: 't'.charCodeAt(),
5506 /** Utf8 data 'u' */
5507 utf8: 'u'.charCodeAt(),
5508 /** MIME message body part 'm' */
5509 mime: 'm'.charCodeAt()
5510 },
5511
5512
5513 /** One pass signature packet type
5514 * @enum {Integer}
5515 * @readonly
5516 */
5517 signature: {
5518 /** 0x00: Signature of a binary document. */
5519 binary: 0,
5520 /** 0x01: Signature of a canonical text document.
5521 *
5522 * Canonicalyzing the document by converting line endings. */
5523 text: 1,
5524 /** 0x02: Standalone signature.
5525 *
5526 * This signature is a signature of only its own subpacket contents.
5527 * It is calculated identically to a signature over a zero-lengh
5528 * binary document. Note that it doesn't make sense to have a V3
5529 * standalone signature. */
5530 standalone: 2,
5531 /** 0x10: Generic certification of a User ID and Public-Key packet.
5532 *
5533 * The issuer of this certification does not make any particular
5534 * assertion as to how well the certifier has checked that the owner
5535 * of the key is in fact the person described by the User ID. */
5536 certGeneric: 16,
5537 /** 0x11: Persona certification of a User ID and Public-Key packet.
5538 *
5539 * The issuer of this certification has not done any verification of
5540 * the claim that the owner of this key is the User ID specified. */
5541 certPersona: 17,
5542 /** 0x12: Casual certification of a User ID and Public-Key packet.
5543 *
5544 * The issuer of this certification has done some casual
5545 * verification of the claim of identity. */
5546 certCasual: 18,
5547 /** 0x13: Positive certification of a User ID and Public-Key packet.
5548 *
5549 * The issuer of this certification has done substantial
5550 * verification of the claim of identity.
5551 *
5552 * Most OpenPGP implementations make their "key signatures" as 0x10
5553 * certifications. Some implementations can issue 0x11-0x13
5554 * certifications, but few differentiate between the types. */
5555 certPositive: 19,
5556 /** 0x30: Certification revocation signature
5557 *
5558 * This signature revokes an earlier User ID certification signature
5559 * (signature class 0x10 through 0x13) or direct-key signature
5560 * (0x1F). It should be issued by the same key that issued the
5561 * revoked signature or an authorized revocation key. The signature
5562 * is computed over the same data as the certificate that it
5563 * revokes, and should have a later creation date than that
5564 * certificate. */
5565 certRevocation: 48,
5566 /** 0x18: Subkey Binding Signature
5567 *
5568 * This signature is a statement by the top-level signing key that
5569 * indicates that it owns the subkey. This signature is calculated
5570 * directly on the primary key and subkey, and not on any User ID or
5571 * other packets. A signature that binds a signing subkey MUST have
5572 * an Embedded Signature subpacket in this binding signature that
5573 * contains a 0x19 signature made by the signing subkey on the
5574 * primary key and subkey. */
5575 subkeyBinding: 24,
5576 /** 0x19: Primary Key Binding Signature
5577 *
5578 * This signature is a statement by a signing subkey, indicating
5579 * that it is owned by the primary key and subkey. This signature
5580 * is calculated the same way as a 0x18 signature: directly on the
5581 * primary key and subkey, and not on any User ID or other packets.
5582 *
5583 * When a signature is made over a key, the hash data starts with the
5584 * octet 0x99, followed by a two-octet length of the key, and then body
5585 * of the key packet. (Note that this is an old-style packet header for
5586 * a key packet with two-octet length.) A subkey binding signature
5587 * (type 0x18) or primary key binding signature (type 0x19) then hashes
5588 * the subkey using the same format as the main key (also using 0x99 as
5589 * the first octet). */
5590 keyBinding: 25,
5591 /** 0x1F: Signature directly on a key
5592 *
5593 * This signature is calculated directly on a key. It binds the
5594 * information in the Signature subpackets to the key, and is
5595 * appropriate to be used for subpackets that provide information
5596 * about the key, such as the Revocation Key subpacket. It is also
5597 * appropriate for statements that non-self certifiers want to make
5598 * about the key itself, rather than the binding between a key and a
5599 * name. */
5600 key: 31,
5601 /** 0x20: Key revocation signature
5602 *
5603 * The signature is calculated directly on the key being revoked. A
5604 * revoked key is not to be used. Only revocation signatures by the
5605 * key being revoked, or by an authorized revocation key, should be
5606 * considered valid revocation signatures.a */
5607 keyRevocation: 32,
5608 /** 0x28: Subkey revocation signature
5609 *
5610 * The signature is calculated directly on the subkey being revoked.
5611 * A revoked subkey is not to be used. Only revocation signatures
5612 * by the top-level signature key that is bound to this subkey, or
5613 * by an authorized revocation key, should be considered valid
5614 * revocation signatures.
5615 *
5616 * Key revocation signatures (types 0x20 and 0x28)
5617 * hash only the key being revoked. */
5618 subkeyRevocation: 40,
5619 /** 0x40: Timestamp signature.
5620 * This signature is only meaningful for the timestamp contained in
5621 * it. */
5622 timestamp: 64,
5623 /** 0x50: Third-Party Confirmation signature.
5624 *
5625 * This signature is a signature over some other OpenPGP Signature
5626 * packet(s). It is analogous to a notary seal on the signed data.
5627 * A third-party signature SHOULD include Signature Target
5628 * subpacket(s) to give easy identification. Note that we really do
5629 * mean SHOULD. There are plausible uses for this (such as a blind
5630 * party that only sees the signature, not the key or source
5631 * document) that cannot include a target subpacket. */
5632 thirdParty: 80
5633 },
5634
5635 /** Signature subpacket type
5636 * @enum {Integer}
5637 * @readonly
5638 */
5639 signatureSubpacket: {
5640 signatureCreationTime: 2,
5641 signatureExpirationTime: 3,
5642 exportableCertification: 4,
5643 trustSignature: 5,
5644 regularExpression: 6,
5645 revocable: 7,
5646 keyExpirationTime: 9,
5647 placeholderBackwardsCompatibility: 10,
5648 preferredSymmetricAlgorithms: 11,
5649 revocationKey: 12,
5650 issuer: 16,
5651 notationData: 20,
5652 preferredHashAlgorithms: 21,
5653 preferredCompressionAlgorithms: 22,
5654 keyServerPreferences: 23,
5655 preferredKeyServer: 24,
5656 primaryUserId: 25,
5657 policyUri: 26,
5658 keyFlags: 27,
5659 signersUserId: 28,
5660 reasonForRevocation: 29,
5661 features: 30,
5662 signatureTarget: 31,
5663 embeddedSignature: 32,
5664 issuerFingerprint: 33,
5665 preferredAeadAlgorithms: 34
5666 },
5667
5668 /** Key flags
5669 * @enum {Integer}
5670 * @readonly
5671 */
5672 keyFlags: {
5673 /** 0x01 - This key may be used to certify other keys. */
5674 certifyKeys: 1,
5675 /** 0x02 - This key may be used to sign data. */
5676 signData: 2,
5677 /** 0x04 - This key may be used to encrypt communications. */
5678 encryptCommunication: 4,
5679 /** 0x08 - This key may be used to encrypt storage. */
5680 encryptStorage: 8,
5681 /** 0x10 - The private component of this key may have been split
5682 * by a secret-sharing mechanism. */
5683 splitPrivateKey: 16,
5684 /** 0x20 - This key may be used for authentication. */
5685 authentication: 32,
5686 /** 0x80 - The private component of this key may be in the
5687 * possession of more than one person. */
5688 sharedPrivateKey: 128
5689 },
5690
5691 /** Armor type
5692 * @enum {Integer}
5693 * @readonly
5694 */
5695 armor: {
5696 multipartSection: 0,
5697 multipartLast: 1,
5698 signed: 2,
5699 message: 3,
5700 publicKey: 4,
5701 privateKey: 5,
5702 signature: 6
5703 },
5704
5705 /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
5706 * @enum {Integer}
5707 * @readonly
5708 */
5709 reasonForRevocation: {
5710 /** No reason specified (key revocations or cert revocations) */
5711 noReason: 0,
5712 /** Key is superseded (key revocations) */
5713 keySuperseded: 1,
5714 /** Key material has been compromised (key revocations) */
5715 keyCompromised: 2,
5716 /** Key is retired and no longer used (key revocations) */
5717 keyRetired: 3,
5718 /** User ID information is no longer valid (cert revocations) */
5719 userIdInvalid: 32
5720 },
5721
5722 /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
5723 * @enum {Integer}
5724 * @readonly
5725 */
5726 features: {
5727 /** 0x01 - Modification Detection (packets 18 and 19) */
5728 modificationDetection: 1,
5729 /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
5730 * Symmetric-Key Encrypted Session Key Packets (packet 3) */
5731 aead: 2,
5732 /** 0x04 - Version 5 Public-Key Packet format and corresponding new
5733 * fingerprint format */
5734 v5Keys: 4
5735 },
5736
5737 /** Asserts validity and converts from string/integer to integer. */
5738 write: function(type, e) {
5739 if (typeof e === 'number') {
5740 e = this.read(type, e);
5741 }
5742
5743 if (type[e] !== undefined) {
5744 return type[e];
5745 }
5746
5747 throw new Error('Invalid enum value.');
5748 },
5749
5750 /** Converts from an integer to string. */
5751 read: function(type, e) {
5752 if (!type[byValue]) {
5753 type[byValue] = [];
5754 Object.entries(type).forEach(([key, value]) => {
5755 type[byValue][value] = key;
5756 });
5757 }
5758
5759 if (type[byValue][e] !== undefined) {
5760 return type[byValue][e];
5761 }
5762
5763 throw new Error('Invalid enum value.');
5764 }
5765
5766};
5767
5768// GPG4Browsers - An OpenPGP implementation in javascript
5769
5770var defaultConfig = {
5771 /**
5772 * @memberof module:config
5773 * @property {Integer} preferHashAlgorithm Default hash algorithm {@link module:enums.hash}
5774 */
5775 preferHashAlgorithm: enums.hash.sha256,
5776 /**
5777 * @memberof module:config
5778 * @property {Integer} encryptionCipher Default encryption cipher {@link module:enums.symmetric}
5779 */
5780 encryptionCipher: enums.symmetric.aes256,
5781 /**
5782 * @memberof module:config
5783 * @property {Integer} compression Default compression algorithm {@link module:enums.compression}
5784 */
5785 compression: enums.compression.uncompressed,
5786 /**
5787 * @memberof module:config
5788 * @property {Integer} deflateLevel Default zip/zlib compression level, between 1 and 9
5789 */
5790 deflateLevel: 6,
5791
5792 /**
5793 * Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption.
5794 * Note: not all OpenPGP implementations are compatible with this option.
5795 * **FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION**
5796 * @see {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07|RFC4880bis-07}
5797 * @memberof module:config
5798 * @property {Boolean} aeadProtect
5799 */
5800 aeadProtect: false,
5801 /**
5802 * Default Authenticated Encryption with Additional Data (AEAD) encryption mode
5803 * Only has an effect when aeadProtect is set to true.
5804 * @memberof module:config
5805 * @property {Integer} aeadMode Default AEAD mode {@link module:enums.aead}
5806 */
5807 aeadMode: enums.aead.eax,
5808 /**
5809 * Chunk Size Byte for Authenticated Encryption with Additional Data (AEAD) mode
5810 * Only has an effect when aeadProtect is set to true.
5811 * Must be an integer value from 0 to 56.
5812 * @memberof module:config
5813 * @property {Integer} aeadChunkSizeByte
5814 */
5815 aeadChunkSizeByte: 12,
5816 /**
5817 * Use V5 keys.
5818 * Note: not all OpenPGP implementations are compatible with this option.
5819 * **FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION**
5820 * @memberof module:config
5821 * @property {Boolean} v5Keys
5822 */
5823 v5Keys: false,
5824 /**
5825 * {@link https://tools.ietf.org/html/rfc4880#section-3.7.1.3|RFC4880 3.7.1.3}:
5826 * Iteration Count Byte for S2K (String to Key)
5827 * @memberof module:config
5828 * @property {Integer} s2kIterationCountByte
5829 */
5830 s2kIterationCountByte: 224,
5831 /**
5832 * Allow decryption of messages without integrity protection.
5833 * This is an **insecure** setting:
5834 * - message modifications cannot be detected, thus processing the decrypted data is potentially unsafe.
5835 * - it enables downgrade attacks against integrity-protected messages.
5836 * @memberof module:config
5837 * @property {Boolean} allowUnauthenticatedMessages
5838 */
5839 allowUnauthenticatedMessages: false,
5840 /**
5841 * Allow streaming unauthenticated data before its integrity has been checked.
5842 * This setting is **insecure** if the partially decrypted message is processed further or displayed to the user.
5843 * @memberof module:config
5844 * @property {Boolean} allowUnauthenticatedStream
5845 */
5846 allowUnauthenticatedStream: false,
5847 /**
5848 * @memberof module:config
5849 * @property {Boolean} checksumRequired Do not throw error when armor is missing a checksum
5850 */
5851 checksumRequired: false,
5852 /**
5853 * @memberof module:config
5854 * @property {Number} minRsaBits Minimum RSA key size allowed for key generation
5855 */
5856 minRsaBits: 2048,
5857 /**
5858 * Work-around for rare GPG decryption bug when encrypting with multiple passwords.
5859 * **Slower and slightly less secure**
5860 * @memberof module:config
5861 * @property {Boolean} passwordCollisionCheck
5862 */
5863 passwordCollisionCheck: false,
5864 /**
5865 * @memberof module:config
5866 * @property {Boolean} revocationsExpire If true, expired revocation signatures are ignored
5867 */
5868 revocationsExpire: false,
5869 /**
5870 * Allow decryption using RSA keys without `encrypt` flag.
5871 * This setting is potentially insecure, but it is needed to get around an old openpgpjs bug
5872 * where key flags were ignored when selecting a key for encryption.
5873 * @memberof module:config
5874 * @property {Boolean} allowInsecureDecryptionWithSigningKeys
5875 */
5876 allowInsecureDecryptionWithSigningKeys: false,
5877
5878 /**
5879 * @memberof module:config
5880 * @property {Integer} minBytesForWebCrypto The minimum amount of bytes for which to use native WebCrypto APIs when available
5881 */
5882 minBytesForWebCrypto: 1000,
5883 /**
5884 * @memberof module:config
5885 * @property {Boolean} tolerant Ignore unsupported/unrecognizable packets instead of throwing an error
5886 */
5887 tolerant: true,
5888
5889 /**
5890 * @memberof module:config
5891 * @property {Boolean} showVersion Whether to include {@link module:config/config.versionString} in armored messages
5892 */
5893 showVersion: false,
5894 /**
5895 * @memberof module:config
5896 * @property {Boolean} showComment Whether to include {@link module:config/config.commentString} in armored messages
5897 */
5898 showComment: false,
5899 /**
5900 * @memberof module:config
5901 * @property {String} versionString A version string to be included in armored messages
5902 */
5903 versionString: "OpenPGP.js 5.0.0-1",
5904 /**
5905 * @memberof module:config
5906 * @property {String} commentString A comment string to be included in armored messages
5907 */
5908 commentString: "https://openpgpjs.org",
5909
5910 /**
5911 * Max userid string length (used for parsing)
5912 * @memberof module:config
5913 * @property {Integer} maxUseridLength
5914 */
5915 maxUseridLength: 1024 * 5,
5916 /**
5917 * Contains notatations that are considered "known". Known notations do not trigger
5918 * validation error when the notation is marked as critical.
5919 * @memberof module:config
5920 * @property {Array} knownNotations
5921 */
5922 knownNotations: ["preferred-email-encoding@pgp.com", "pka-address@gnupg.org"],
5923 /**
5924 * @memberof module:config
5925 * @property {Boolean} useIndutnyElliptic Whether to use the indutny/elliptic library. When false, certain curves will not be supported.
5926 */
5927 useIndutnyElliptic: true,
5928 /**
5929 * @memberof module:config
5930 * @property {Set<Integer>} reject_hash_algorithms Reject insecure hash algorithms {@link module:enums.hash}
5931 */
5932 rejectHashAlgorithms: new globalThis.Set([enums.hash.md5, enums.hash.ripemd]),
5933 /**
5934 * @memberof module:config
5935 * @property {Set<Integer>} reject_message_hash_algorithms Reject insecure message hash algorithms {@link module:enums.hash}
5936 */
5937 rejectMessageHashAlgorithms: new globalThis.Set([enums.hash.md5, enums.hash.ripemd, enums.hash.sha1])
5938};
5939
5940// GPG4Browsers - An OpenPGP implementation in javascript
5941
5942/**
5943 * Finds out which Ascii Armoring type is used. Throws error if unknown type.
5944 * @param {String} text - ascii armored text
5945 * @returns {Integer} 0 = MESSAGE PART n of m.
5946 * 1 = MESSAGE PART n
5947 * 2 = SIGNED MESSAGE
5948 * 3 = PGP MESSAGE
5949 * 4 = PUBLIC KEY BLOCK
5950 * 5 = PRIVATE KEY BLOCK
5951 * 6 = SIGNATURE
5952 * @private
5953 */
5954function getType(text) {
5955 const reHeader = /^-----BEGIN PGP (MESSAGE, PART \d+\/\d+|MESSAGE, PART \d+|SIGNED MESSAGE|MESSAGE|PUBLIC KEY BLOCK|PRIVATE KEY BLOCK|SIGNATURE)-----$/m;
5956
5957 const header = text.match(reHeader);
5958
5959 if (!header) {
5960 throw new Error('Unknown ASCII armor type');
5961 }
5962
5963 // BEGIN PGP MESSAGE, PART X/Y
5964 // Used for multi-part messages, where the armor is split amongst Y
5965 // parts, and this is the Xth part out of Y.
5966 if (/MESSAGE, PART \d+\/\d+/.test(header[1])) {
5967 return enums.armor.multipartSection;
5968 } else
5969 // BEGIN PGP MESSAGE, PART X
5970 // Used for multi-part messages, where this is the Xth part of an
5971 // unspecified number of parts. Requires the MESSAGE-ID Armor
5972 // Header to be used.
5973 if (/MESSAGE, PART \d+/.test(header[1])) {
5974 return enums.armor.multipartLast;
5975 } else
5976 // BEGIN PGP SIGNED MESSAGE
5977 if (/SIGNED MESSAGE/.test(header[1])) {
5978 return enums.armor.signed;
5979 } else
5980 // BEGIN PGP MESSAGE
5981 // Used for signed, encrypted, or compressed files.
5982 if (/MESSAGE/.test(header[1])) {
5983 return enums.armor.message;
5984 } else
5985 // BEGIN PGP PUBLIC KEY BLOCK
5986 // Used for armoring public keys.
5987 if (/PUBLIC KEY BLOCK/.test(header[1])) {
5988 return enums.armor.publicKey;
5989 } else
5990 // BEGIN PGP PRIVATE KEY BLOCK
5991 // Used for armoring private keys.
5992 if (/PRIVATE KEY BLOCK/.test(header[1])) {
5993 return enums.armor.privateKey;
5994 } else
5995 // BEGIN PGP SIGNATURE
5996 // Used for detached signatures, OpenPGP/MIME signatures, and
5997 // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE
5998 // for detached signatures.
5999 if (/SIGNATURE/.test(header[1])) {
6000 return enums.armor.signature;
6001 }
6002}
6003
6004/**
6005 * Add additional information to the armor version of an OpenPGP binary
6006 * packet block.
6007 * @author Alex
6008 * @version 2011-12-16
6009 * @param {String} [customComment] - Additional comment to add to the armored string
6010 * @returns {String} The header information.
6011 * @private
6012 */
6013function addheader(customComment, config) {
6014 let result = "";
6015 if (config.showVersion) {
6016 result += "Version: " + config.versionString + '\n';
6017 }
6018 if (config.showComment) {
6019 result += "Comment: " + config.commentString + '\n';
6020 }
6021 if (customComment) {
6022 result += "Comment: " + customComment + '\n';
6023 }
6024 result += '\n';
6025 return result;
6026}
6027
6028
6029/**
6030 * Calculates a checksum over the given data and returns it base64 encoded
6031 * @param {String | ReadableStream<String>} data - Data to create a CRC-24 checksum for
6032 * @returns {String | ReadableStream<String>} Base64 encoded checksum.
6033 * @private
6034 */
6035function getCheckSum(data) {
6036 const crc = createcrc24(data);
6037 return encode(crc);
6038}
6039
6040// https://create.stephan-brumme.com/crc32/#slicing-by-8-overview
6041
6042const crc_table = [
6043 new Array(0xFF),
6044 new Array(0xFF),
6045 new Array(0xFF),
6046 new Array(0xFF)
6047];
6048
6049for (let i = 0; i <= 0xFF; i++) {
6050 let crc = i << 16;
6051 for (let j = 0; j < 8; j++) {
6052 crc = (crc << 1) ^ ((crc & 0x800000) !== 0 ? 0x864CFB : 0);
6053 }
6054 crc_table[0][i] =
6055 ((crc & 0xFF0000) >> 16) |
6056 (crc & 0x00FF00) |
6057 ((crc & 0x0000FF) << 16);
6058}
6059for (let i = 0; i <= 0xFF; i++) {
6060 crc_table[1][i] = (crc_table[0][i] >> 8) ^ crc_table[0][crc_table[0][i] & 0xFF];
6061}
6062for (let i = 0; i <= 0xFF; i++) {
6063 crc_table[2][i] = (crc_table[1][i] >> 8) ^ crc_table[0][crc_table[1][i] & 0xFF];
6064}
6065for (let i = 0; i <= 0xFF; i++) {
6066 crc_table[3][i] = (crc_table[2][i] >> 8) ^ crc_table[0][crc_table[2][i] & 0xFF];
6067}
6068
6069// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#Endianness
6070const isLittleEndian = (function() {
6071 const buffer = new ArrayBuffer(2);
6072 new DataView(buffer).setInt16(0, 0xFF, true /* littleEndian */);
6073 // Int16Array uses the platform's endianness.
6074 return new Int16Array(buffer)[0] === 0xFF;
6075}());
6076
6077/**
6078 * Internal function to calculate a CRC-24 checksum over a given string (data)
6079 * @param {String | ReadableStream<String>} input - Data to create a CRC-24 checksum for
6080 * @returns {Uint8Array | ReadableStream<Uint8Array>} The CRC-24 checksum.
6081 * @private
6082 */
6083function createcrc24(input) {
6084 let crc = 0xCE04B7;
6085 return stream.transform(input, value => {
6086 const len32 = isLittleEndian ? Math.floor(value.length / 4) : 0;
6087 const arr32 = new Uint32Array(value.buffer, value.byteOffset, len32);
6088 for (let i = 0; i < len32; i++) {
6089 crc ^= arr32[i];
6090 crc =
6091 crc_table[0][(crc >> 24) & 0xFF] ^
6092 crc_table[1][(crc >> 16) & 0xFF] ^
6093 crc_table[2][(crc >> 8) & 0xFF] ^
6094 crc_table[3][(crc >> 0) & 0xFF];
6095 }
6096 for (let i = len32 * 4; i < value.length; i++) {
6097 crc = (crc >> 8) ^ crc_table[0][(crc & 0xFF) ^ value[i]];
6098 }
6099 }, () => new Uint8Array([crc, crc >> 8, crc >> 16]));
6100}
6101
6102/**
6103 * Verify armored headers. RFC4880, section 6.3: "OpenPGP should consider improperly formatted
6104 * Armor Headers to be corruption of the ASCII Armor."
6105 * @private
6106 * @param {Array<String>} headers - Armor headers
6107 */
6108function verifyHeaders(headers) {
6109 for (let i = 0; i < headers.length; i++) {
6110 if (!/^([^\s:]|[^\s:][^:]*[^\s:]): .+$/.test(headers[i])) {
6111 throw new Error('Improperly formatted armor header: ' + headers[i]);
6112 }
6113 if (!/^(Version|Comment|MessageID|Hash|Charset): .+$/.test(headers[i])) {
6114 util.printDebugError(new Error('Unknown header: ' + headers[i]));
6115 }
6116 }
6117}
6118
6119/**
6120 * Splits a message into two parts, the body and the checksum. This is an internal function
6121 * @param {String} text - OpenPGP armored message part
6122 * @returns {Object} An object with attribute "body" containing the body.
6123 * and an attribute "checksum" containing the checksum.
6124 * @private
6125 */
6126function splitChecksum(text) {
6127 let body = text;
6128 let checksum = "";
6129
6130 const lastEquals = text.lastIndexOf("=");
6131
6132 if (lastEquals >= 0 && lastEquals !== text.length - 1) { // '=' as the last char means no checksum
6133 body = text.slice(0, lastEquals);
6134 checksum = text.slice(lastEquals + 1).substr(0, 4);
6135 }
6136
6137 return { body: body, checksum: checksum };
6138}
6139
6140/**
6141 * Dearmor an OpenPGP armored message; verify the checksum and return
6142 * the encoded bytes
6143 * @param {String} input - OpenPGP armored message
6144 * @returns {Object} An object with attribute "text" containing the message text,
6145 * an attribute "data" containing a stream of bytes and "type" for the ASCII armor type
6146 * @async
6147 * @static
6148 */
6149function unarmor(input, config = defaultConfig) {
6150 return new Promise(async (resolve, reject) => {
6151 try {
6152 const reSplit = /^-----[^-]+-----$/m;
6153 const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;
6154
6155 let type;
6156 const headers = [];
6157 let lastHeaders = headers;
6158 let headersDone;
6159 let text = [];
6160 let textDone;
6161 let checksum;
6162 let data = decode(stream.transformPair(input, async (readable, writable) => {
6163 const reader = stream.getReader(readable);
6164 try {
6165 while (true) {
6166 let line = await reader.readLine();
6167 if (line === undefined) {
6168 throw new Error('Misformed armored text');
6169 }
6170 // remove trailing whitespace at end of lines
6171 line = util.removeTrailingSpaces(line.replace(/[\r\n]/g, ''));
6172 if (!type) {
6173 if (reSplit.test(line)) {
6174 type = getType(line);
6175 }
6176 } else if (!headersDone) {
6177 if (reSplit.test(line)) {
6178 reject(new Error('Mandatory blank line missing between armor headers and armor data'));
6179 }
6180 if (!reEmptyLine.test(line)) {
6181 lastHeaders.push(line);
6182 } else {
6183 verifyHeaders(lastHeaders);
6184 headersDone = true;
6185 if (textDone || type !== 2) {
6186 resolve({ text, data, headers, type });
6187 break;
6188 }
6189 }
6190 } else if (!textDone && type === 2) {
6191 if (!reSplit.test(line)) {
6192 // Reverse dash-escaping for msg
6193 text.push(line.replace(/^- /, ''));
6194 } else {
6195 text = text.join('\r\n');
6196 textDone = true;
6197 verifyHeaders(lastHeaders);
6198 lastHeaders = [];
6199 headersDone = false;
6200 }
6201 }
6202 }
6203 } catch (e) {
6204 reject(e);
6205 return;
6206 }
6207 const writer = stream.getWriter(writable);
6208 try {
6209 while (true) {
6210 await writer.ready;
6211 const { done, value } = await reader.read();
6212 if (done) {
6213 throw new Error('Misformed armored text');
6214 }
6215 const line = value + '';
6216 if (line.indexOf('=') === -1 && line.indexOf('-') === -1) {
6217 await writer.write(line);
6218 } else {
6219 let remainder = await reader.readToEnd();
6220 if (!remainder.length) remainder = '';
6221 remainder = line + remainder;
6222 remainder = util.removeTrailingSpaces(remainder.replace(/\r/g, ''));
6223 const parts = remainder.split(reSplit);
6224 if (parts.length === 1) {
6225 throw new Error('Misformed armored text');
6226 }
6227 const split = splitChecksum(parts[0].slice(0, -1));
6228 checksum = split.checksum;
6229 await writer.write(split.body);
6230 break;
6231 }
6232 }
6233 await writer.ready;
6234 await writer.close();
6235 } catch (e) {
6236 await writer.abort(e);
6237 }
6238 }));
6239 data = stream.transformPair(data, async (readable, writable) => {
6240 const checksumVerified = stream.readToEnd(getCheckSum(stream.passiveClone(readable)));
6241 checksumVerified.catch(() => {});
6242 await stream.pipe(readable, writable, {
6243 preventClose: true
6244 });
6245 const writer = stream.getWriter(writable);
6246 try {
6247 const checksumVerifiedString = (await checksumVerified).replace('\n', '');
6248 if (checksum !== checksumVerifiedString && (checksum || config.checksumRequired)) {
6249 throw new Error("Ascii armor integrity check on message failed: '" + checksum + "' should be '" +
6250 checksumVerifiedString + "'");
6251 }
6252 await writer.ready;
6253 await writer.close();
6254 } catch (e) {
6255 await writer.abort(e);
6256 }
6257 });
6258 } catch (e) {
6259 reject(e);
6260 }
6261 });
6262}
6263
6264
6265/**
6266 * Armor an OpenPGP binary packet block
6267 * @param {module:enums.armor} messageType - Type of the message
6268 * @param {Uint8Array | ReadableStream<Uint8Array>} body - The message body to armor
6269 * @param {Integer} [partIndex]
6270 * @param {Integer} [partTotal]
6271 * @param {String} [customComment] - Additional comment to add to the armored string
6272 * @returns {String | ReadableStream<String>} Armored text.
6273 * @static
6274 */
6275function armor(messageType, body, partIndex, partTotal, customComment, config = defaultConfig) {
6276 let text;
6277 let hash;
6278 if (messageType === enums.armor.signed) {
6279 text = body.text;
6280 hash = body.hash;
6281 body = body.data;
6282 }
6283 const bodyClone = stream.passiveClone(body);
6284 const result = [];
6285 switch (messageType) {
6286 case enums.armor.multipartSection:
6287 result.push("-----BEGIN PGP MESSAGE, PART " + partIndex + "/" + partTotal + "-----\n");
6288 result.push(addheader(customComment, config));
6289 result.push(encode(body));
6290 result.push("=", getCheckSum(bodyClone));
6291 result.push("-----END PGP MESSAGE, PART " + partIndex + "/" + partTotal + "-----\n");
6292 break;
6293 case enums.armor.multipartLast:
6294 result.push("-----BEGIN PGP MESSAGE, PART " + partIndex + "-----\n");
6295 result.push(addheader(customComment, config));
6296 result.push(encode(body));
6297 result.push("=", getCheckSum(bodyClone));
6298 result.push("-----END PGP MESSAGE, PART " + partIndex + "-----\n");
6299 break;
6300 case enums.armor.signed:
6301 result.push("\n-----BEGIN PGP SIGNED MESSAGE-----\n");
6302 result.push("Hash: " + hash + "\n\n");
6303 result.push(text.replace(/^-/mg, "- -"));
6304 result.push("\n-----BEGIN PGP SIGNATURE-----\n");
6305 result.push(addheader(customComment, config));
6306 result.push(encode(body));
6307 result.push("=", getCheckSum(bodyClone));
6308 result.push("-----END PGP SIGNATURE-----\n");
6309 break;
6310 case enums.armor.message:
6311 result.push("-----BEGIN PGP MESSAGE-----\n");
6312 result.push(addheader(customComment, config));
6313 result.push(encode(body));
6314 result.push("=", getCheckSum(bodyClone));
6315 result.push("-----END PGP MESSAGE-----\n");
6316 break;
6317 case enums.armor.publicKey:
6318 result.push("-----BEGIN PGP PUBLIC KEY BLOCK-----\n");
6319 result.push(addheader(customComment, config));
6320 result.push(encode(body));
6321 result.push("=", getCheckSum(bodyClone));
6322 result.push("-----END PGP PUBLIC KEY BLOCK-----\n");
6323 break;
6324 case enums.armor.privateKey:
6325 result.push("-----BEGIN PGP PRIVATE KEY BLOCK-----\n");
6326 result.push(addheader(customComment, config));
6327 result.push(encode(body));
6328 result.push("=", getCheckSum(bodyClone));
6329 result.push("-----END PGP PRIVATE KEY BLOCK-----\n");
6330 break;
6331 case enums.armor.signature:
6332 result.push("-----BEGIN PGP SIGNATURE-----\n");
6333 result.push(addheader(customComment, config));
6334 result.push(encode(body));
6335 result.push("=", getCheckSum(bodyClone));
6336 result.push("-----END PGP SIGNATURE-----\n");
6337 break;
6338 }
6339
6340 return util.concat(result);
6341}
6342
6343// GPG4Browsers - An OpenPGP implementation in javascript
6344
6345/**
6346 * Implementation of type key id
6347 *
6348 * {@link https://tools.ietf.org/html/rfc4880#section-3.3|RFC4880 3.3}:
6349 * A Key ID is an eight-octet scalar that identifies a key.
6350 * Implementations SHOULD NOT assume that Key IDs are unique. The
6351 * section "Enhanced Key Formats" below describes how Key IDs are
6352 * formed.
6353 */
6354class Keyid {
6355 constructor() {
6356 this.bytes = '';
6357 }
6358
6359 /**
6360 * Parsing method for a key id
6361 * @param {Uint8Array} bytes - Input to read the key id from
6362 */
6363 read(bytes) {
6364 this.bytes = util.uint8ArrayToStr(bytes.subarray(0, 8));
6365 }
6366
6367 /**
6368 * Serializes the Key ID
6369 * @returns {Uint8Array} Key ID as a Uint8Array.
6370 */
6371 write() {
6372 return util.strToUint8Array(this.bytes);
6373 }
6374
6375 /**
6376 * Returns the Key ID represented as a hexadecimal string
6377 * @returns {String} Key ID as a hexadecimal string.
6378 */
6379 toHex() {
6380 return util.strToHex(this.bytes);
6381 }
6382
6383 /**
6384 * Checks equality of Key ID's
6385 * @param {Keyid} keyid
6386 * @param {Boolean} matchWildcard - Indicates whether to check if either keyid is a wildcard
6387 */
6388 equals(keyid, matchWildcard = false) {
6389 return (matchWildcard && (keyid.isWildcard() || this.isWildcard())) || this.bytes === keyid.bytes;
6390 }
6391
6392 /**
6393 * Checks to see if the Key ID is unset
6394 * @returns {Boolean} True if the Key ID is null.
6395 */
6396 isNull() {
6397 return this.bytes === '';
6398 }
6399
6400 /**
6401 * Checks to see if the Key ID is a "wildcard" Key ID (all zeros)
6402 * @returns {Boolean} True if this is a wildcard Key ID.
6403 */
6404 isWildcard() {
6405 return /^0+$/.test(this.toHex());
6406 }
6407
6408 static mapToHex(keyId) {
6409 return keyId.toHex();
6410 }
6411
6412 static fromId(hex) {
6413 const keyid = new Keyid();
6414 keyid.read(util.hexToUint8Array(hex));
6415 return keyid;
6416 }
6417
6418 static wildcard() {
6419 const keyid = new Keyid();
6420 keyid.read(new Uint8Array(8));
6421 return keyid;
6422 }
6423}
6424
6425/**
6426 * @file {@link http://asmjs.org Asm.js} implementation of the {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard Advanced Encryption Standard}.
6427 * @author Artem S Vybornov <vybornov@gmail.com>
6428 * @license MIT
6429 */
6430var AES_asm = function () {
6431
6432 /**
6433 * Galois Field stuff init flag
6434 */
6435 var ginit_done = false;
6436
6437 /**
6438 * Galois Field exponentiation and logarithm tables for 3 (the generator)
6439 */
6440 var gexp3, glog3;
6441
6442 /**
6443 * Init Galois Field tables
6444 */
6445 function ginit() {
6446 gexp3 = [],
6447 glog3 = [];
6448
6449 var a = 1, c, d;
6450 for (c = 0; c < 255; c++) {
6451 gexp3[c] = a;
6452
6453 // Multiply by three
6454 d = a & 0x80, a <<= 1, a &= 255;
6455 if (d === 0x80) a ^= 0x1b;
6456 a ^= gexp3[c];
6457
6458 // Set the log table value
6459 glog3[gexp3[c]] = c;
6460 }
6461 gexp3[255] = gexp3[0];
6462 glog3[0] = 0;
6463
6464 ginit_done = true;
6465 }
6466
6467 /**
6468 * Galois Field multiplication
6469 * @param {number} a
6470 * @param {number} b
6471 * @return {number}
6472 */
6473 function gmul(a, b) {
6474 var c = gexp3[(glog3[a] + glog3[b]) % 255];
6475 if (a === 0 || b === 0) c = 0;
6476 return c;
6477 }
6478
6479 /**
6480 * Galois Field reciprocal
6481 * @param {number} a
6482 * @return {number}
6483 */
6484 function ginv(a) {
6485 var i = gexp3[255 - glog3[a]];
6486 if (a === 0) i = 0;
6487 return i;
6488 }
6489
6490 /**
6491 * AES stuff init flag
6492 */
6493 var aes_init_done = false;
6494
6495 /**
6496 * Encryption, Decryption, S-Box and KeyTransform tables
6497 *
6498 * @type {number[]}
6499 */
6500 var aes_sbox;
6501
6502 /**
6503 * @type {number[]}
6504 */
6505 var aes_sinv;
6506
6507 /**
6508 * @type {number[][]}
6509 */
6510 var aes_enc;
6511
6512 /**
6513 * @type {number[][]}
6514 */
6515 var aes_dec;
6516
6517 /**
6518 * Init AES tables
6519 */
6520 function aes_init() {
6521 if (!ginit_done) ginit();
6522
6523 // Calculates AES S-Box value
6524 function _s(a) {
6525 var c, s, x;
6526 s = x = ginv(a);
6527 for (c = 0; c < 4; c++) {
6528 s = ((s << 1) | (s >>> 7)) & 255;
6529 x ^= s;
6530 }
6531 x ^= 99;
6532 return x;
6533 }
6534
6535 // Tables
6536 aes_sbox = [],
6537 aes_sinv = [],
6538 aes_enc = [[], [], [], []],
6539 aes_dec = [[], [], [], []];
6540
6541 for (var i = 0; i < 256; i++) {
6542 var s = _s(i);
6543
6544 // S-Box and its inverse
6545 aes_sbox[i] = s;
6546 aes_sinv[s] = i;
6547
6548 // Ecryption and Decryption tables
6549 aes_enc[0][i] = (gmul(2, s) << 24) | (s << 16) | (s << 8) | gmul(3, s);
6550 aes_dec[0][s] = (gmul(14, i) << 24) | (gmul(9, i) << 16) | (gmul(13, i) << 8) | gmul(11, i);
6551 // Rotate tables
6552 for (var t = 1; t < 4; t++) {
6553 aes_enc[t][i] = (aes_enc[t - 1][i] >>> 8) | (aes_enc[t - 1][i] << 24);
6554 aes_dec[t][s] = (aes_dec[t - 1][s] >>> 8) | (aes_dec[t - 1][s] << 24);
6555 }
6556 }
6557
6558 aes_init_done = true;
6559 }
6560
6561 /**
6562 * Asm.js module constructor.
6563 *
6564 * <p>
6565 * Heap buffer layout by offset:
6566 * <pre>
6567 * 0x0000 encryption key schedule
6568 * 0x0400 decryption key schedule
6569 * 0x0800 sbox
6570 * 0x0c00 inv sbox
6571 * 0x1000 encryption tables
6572 * 0x2000 decryption tables
6573 * 0x3000 reserved (future GCM multiplication lookup table)
6574 * 0x4000 data
6575 * </pre>
6576 * Don't touch anything before <code>0x400</code>.
6577 * </p>
6578 *
6579 * @alias AES_asm
6580 * @class
6581 * @param foreign - <i>ignored</i>
6582 * @param buffer - heap buffer to link with
6583 */
6584 var wrapper = function (foreign, buffer) {
6585 // Init AES stuff for the first time
6586 if (!aes_init_done) aes_init();
6587
6588 // Fill up AES tables
6589 var heap = new Uint32Array(buffer);
6590 heap.set(aes_sbox, 0x0800 >> 2);
6591 heap.set(aes_sinv, 0x0c00 >> 2);
6592 for (var i = 0; i < 4; i++) {
6593 heap.set(aes_enc[i], (0x1000 + 0x400 * i) >> 2);
6594 heap.set(aes_dec[i], (0x2000 + 0x400 * i) >> 2);
6595 }
6596
6597 /**
6598 * Calculate AES key schedules.
6599 * @instance
6600 * @memberof AES_asm
6601 * @param {number} ks - key size, 4/6/8 (for 128/192/256-bit key correspondingly)
6602 * @param {number} k0 - key vector components
6603 * @param {number} k1 - key vector components
6604 * @param {number} k2 - key vector components
6605 * @param {number} k3 - key vector components
6606 * @param {number} k4 - key vector components
6607 * @param {number} k5 - key vector components
6608 * @param {number} k6 - key vector components
6609 * @param {number} k7 - key vector components
6610 */
6611 function set_key(ks, k0, k1, k2, k3, k4, k5, k6, k7) {
6612 var ekeys = heap.subarray(0x000, 60),
6613 dkeys = heap.subarray(0x100, 0x100 + 60);
6614
6615 // Encryption key schedule
6616 ekeys.set([k0, k1, k2, k3, k4, k5, k6, k7]);
6617 for (var i = ks, rcon = 1; i < 4 * ks + 28; i++) {
6618 var k = ekeys[i - 1];
6619 if ((i % ks === 0) || (ks === 8 && i % ks === 4)) {
6620 k = aes_sbox[k >>> 24] << 24 ^ aes_sbox[k >>> 16 & 255] << 16 ^ aes_sbox[k >>> 8 & 255] << 8 ^ aes_sbox[k & 255];
6621 }
6622 if (i % ks === 0) {
6623 k = (k << 8) ^ (k >>> 24) ^ (rcon << 24);
6624 rcon = (rcon << 1) ^ ((rcon & 0x80) ? 0x1b : 0);
6625 }
6626 ekeys[i] = ekeys[i - ks] ^ k;
6627 }
6628
6629 // Decryption key schedule
6630 for (var j = 0; j < i; j += 4) {
6631 for (var jj = 0; jj < 4; jj++) {
6632 var k = ekeys[i - (4 + j) + (4 - jj) % 4];
6633 if (j < 4 || j >= i - 4) {
6634 dkeys[j + jj] = k;
6635 } else {
6636 dkeys[j + jj] = aes_dec[0][aes_sbox[k >>> 24]]
6637 ^ aes_dec[1][aes_sbox[k >>> 16 & 255]]
6638 ^ aes_dec[2][aes_sbox[k >>> 8 & 255]]
6639 ^ aes_dec[3][aes_sbox[k & 255]];
6640 }
6641 }
6642 }
6643
6644 // Set rounds number
6645 asm.set_rounds(ks + 5);
6646 }
6647
6648 // create library object with necessary properties
6649 var stdlib = {Uint8Array: Uint8Array, Uint32Array: Uint32Array};
6650
6651 var asm = function (stdlib, foreign, buffer) {
6652 "use asm";
6653
6654 var S0 = 0, S1 = 0, S2 = 0, S3 = 0,
6655 I0 = 0, I1 = 0, I2 = 0, I3 = 0,
6656 N0 = 0, N1 = 0, N2 = 0, N3 = 0,
6657 M0 = 0, M1 = 0, M2 = 0, M3 = 0,
6658 H0 = 0, H1 = 0, H2 = 0, H3 = 0,
6659 R = 0;
6660
6661 var HEAP = new stdlib.Uint32Array(buffer),
6662 DATA = new stdlib.Uint8Array(buffer);
6663
6664 /**
6665 * AES core
6666 * @param {number} k - precomputed key schedule offset
6667 * @param {number} s - precomputed sbox table offset
6668 * @param {number} t - precomputed round table offset
6669 * @param {number} r - number of inner rounds to perform
6670 * @param {number} x0 - 128-bit input block vector
6671 * @param {number} x1 - 128-bit input block vector
6672 * @param {number} x2 - 128-bit input block vector
6673 * @param {number} x3 - 128-bit input block vector
6674 */
6675 function _core(k, s, t, r, x0, x1, x2, x3) {
6676 k = k | 0;
6677 s = s | 0;
6678 t = t | 0;
6679 r = r | 0;
6680 x0 = x0 | 0;
6681 x1 = x1 | 0;
6682 x2 = x2 | 0;
6683 x3 = x3 | 0;
6684
6685 var t1 = 0, t2 = 0, t3 = 0,
6686 y0 = 0, y1 = 0, y2 = 0, y3 = 0,
6687 i = 0;
6688
6689 t1 = t | 0x400, t2 = t | 0x800, t3 = t | 0xc00;
6690
6691 // round 0
6692 x0 = x0 ^ HEAP[(k | 0) >> 2],
6693 x1 = x1 ^ HEAP[(k | 4) >> 2],
6694 x2 = x2 ^ HEAP[(k | 8) >> 2],
6695 x3 = x3 ^ HEAP[(k | 12) >> 2];
6696
6697 // round 1..r
6698 for (i = 16; (i | 0) <= (r << 4); i = (i + 16) | 0) {
6699 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],
6700 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],
6701 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],
6702 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];
6703 x0 = y0, x1 = y1, x2 = y2, x3 = y3;
6704 }
6705
6706 // final round
6707 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],
6708 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],
6709 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],
6710 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];
6711 }
6712
6713 /**
6714 * ECB mode encryption
6715 * @param {number} x0 - 128-bit input block vector
6716 * @param {number} x1 - 128-bit input block vector
6717 * @param {number} x2 - 128-bit input block vector
6718 * @param {number} x3 - 128-bit input block vector
6719 */
6720 function _ecb_enc(x0, x1, x2, x3) {
6721 x0 = x0 | 0;
6722 x1 = x1 | 0;
6723 x2 = x2 | 0;
6724 x3 = x3 | 0;
6725
6726 _core(
6727 0x0000, 0x0800, 0x1000,
6728 R,
6729 x0,
6730 x1,
6731 x2,
6732 x3
6733 );
6734 }
6735
6736 /**
6737 * ECB mode decryption
6738 * @param {number} x0 - 128-bit input block vector
6739 * @param {number} x1 - 128-bit input block vector
6740 * @param {number} x2 - 128-bit input block vector
6741 * @param {number} x3 - 128-bit input block vector
6742 */
6743 function _ecb_dec(x0, x1, x2, x3) {
6744 x0 = x0 | 0;
6745 x1 = x1 | 0;
6746 x2 = x2 | 0;
6747 x3 = x3 | 0;
6748
6749 var t = 0;
6750
6751 _core(
6752 0x0400, 0x0c00, 0x2000,
6753 R,
6754 x0,
6755 x3,
6756 x2,
6757 x1
6758 );
6759
6760 t = S1, S1 = S3, S3 = t;
6761 }
6762
6763
6764 /**
6765 * CBC mode encryption
6766 * @param {number} x0 - 128-bit input block vector
6767 * @param {number} x1 - 128-bit input block vector
6768 * @param {number} x2 - 128-bit input block vector
6769 * @param {number} x3 - 128-bit input block vector
6770 */
6771 function _cbc_enc(x0, x1, x2, x3) {
6772 x0 = x0 | 0;
6773 x1 = x1 | 0;
6774 x2 = x2 | 0;
6775 x3 = x3 | 0;
6776
6777 _core(
6778 0x0000, 0x0800, 0x1000,
6779 R,
6780 I0 ^ x0,
6781 I1 ^ x1,
6782 I2 ^ x2,
6783 I3 ^ x3
6784 );
6785
6786 I0 = S0,
6787 I1 = S1,
6788 I2 = S2,
6789 I3 = S3;
6790 }
6791
6792 /**
6793 * CBC mode decryption
6794 * @param {number} x0 - 128-bit input block vector
6795 * @param {number} x1 - 128-bit input block vector
6796 * @param {number} x2 - 128-bit input block vector
6797 * @param {number} x3 - 128-bit input block vector
6798 */
6799 function _cbc_dec(x0, x1, x2, x3) {
6800 x0 = x0 | 0;
6801 x1 = x1 | 0;
6802 x2 = x2 | 0;
6803 x3 = x3 | 0;
6804
6805 var t = 0;
6806
6807 _core(
6808 0x0400, 0x0c00, 0x2000,
6809 R,
6810 x0,
6811 x3,
6812 x2,
6813 x1
6814 );
6815
6816 t = S1, S1 = S3, S3 = t;
6817
6818 S0 = S0 ^ I0,
6819 S1 = S1 ^ I1,
6820 S2 = S2 ^ I2,
6821 S3 = S3 ^ I3;
6822
6823 I0 = x0,
6824 I1 = x1,
6825 I2 = x2,
6826 I3 = x3;
6827 }
6828
6829 /**
6830 * CFB mode encryption
6831 * @param {number} x0 - 128-bit input block vector
6832 * @param {number} x1 - 128-bit input block vector
6833 * @param {number} x2 - 128-bit input block vector
6834 * @param {number} x3 - 128-bit input block vector
6835 */
6836 function _cfb_enc(x0, x1, x2, x3) {
6837 x0 = x0 | 0;
6838 x1 = x1 | 0;
6839 x2 = x2 | 0;
6840 x3 = x3 | 0;
6841
6842 _core(
6843 0x0000, 0x0800, 0x1000,
6844 R,
6845 I0,
6846 I1,
6847 I2,
6848 I3
6849 );
6850
6851 I0 = S0 = S0 ^ x0,
6852 I1 = S1 = S1 ^ x1,
6853 I2 = S2 = S2 ^ x2,
6854 I3 = S3 = S3 ^ x3;
6855 }
6856
6857
6858 /**
6859 * CFB mode decryption
6860 * @param {number} x0 - 128-bit input block vector
6861 * @param {number} x1 - 128-bit input block vector
6862 * @param {number} x2 - 128-bit input block vector
6863 * @param {number} x3 - 128-bit input block vector
6864 */
6865 function _cfb_dec(x0, x1, x2, x3) {
6866 x0 = x0 | 0;
6867 x1 = x1 | 0;
6868 x2 = x2 | 0;
6869 x3 = x3 | 0;
6870
6871 _core(
6872 0x0000, 0x0800, 0x1000,
6873 R,
6874 I0,
6875 I1,
6876 I2,
6877 I3
6878 );
6879
6880 S0 = S0 ^ x0,
6881 S1 = S1 ^ x1,
6882 S2 = S2 ^ x2,
6883 S3 = S3 ^ x3;
6884
6885 I0 = x0,
6886 I1 = x1,
6887 I2 = x2,
6888 I3 = x3;
6889 }
6890
6891 /**
6892 * OFB mode encryption / decryption
6893 * @param {number} x0 - 128-bit input block vector
6894 * @param {number} x1 - 128-bit input block vector
6895 * @param {number} x2 - 128-bit input block vector
6896 * @param {number} x3 - 128-bit input block vector
6897 */
6898 function _ofb(x0, x1, x2, x3) {
6899 x0 = x0 | 0;
6900 x1 = x1 | 0;
6901 x2 = x2 | 0;
6902 x3 = x3 | 0;
6903
6904 _core(
6905 0x0000, 0x0800, 0x1000,
6906 R,
6907 I0,
6908 I1,
6909 I2,
6910 I3
6911 );
6912
6913 I0 = S0,
6914 I1 = S1,
6915 I2 = S2,
6916 I3 = S3;
6917
6918 S0 = S0 ^ x0,
6919 S1 = S1 ^ x1,
6920 S2 = S2 ^ x2,
6921 S3 = S3 ^ x3;
6922 }
6923
6924 /**
6925 * CTR mode encryption / decryption
6926 * @param {number} x0 - 128-bit input block vector
6927 * @param {number} x1 - 128-bit input block vector
6928 * @param {number} x2 - 128-bit input block vector
6929 * @param {number} x3 - 128-bit input block vector
6930 */
6931 function _ctr(x0, x1, x2, x3) {
6932 x0 = x0 | 0;
6933 x1 = x1 | 0;
6934 x2 = x2 | 0;
6935 x3 = x3 | 0;
6936
6937 _core(
6938 0x0000, 0x0800, 0x1000,
6939 R,
6940 N0,
6941 N1,
6942 N2,
6943 N3
6944 );
6945
6946 N3 = (~M3 & N3) | M3 & (N3 + 1);
6947 N2 = (~M2 & N2) | M2 & (N2 + ((N3 | 0) == 0));
6948 N1 = (~M1 & N1) | M1 & (N1 + ((N2 | 0) == 0));
6949 N0 = (~M0 & N0) | M0 & (N0 + ((N1 | 0) == 0));
6950
6951 S0 = S0 ^ x0;
6952 S1 = S1 ^ x1;
6953 S2 = S2 ^ x2;
6954 S3 = S3 ^ x3;
6955 }
6956
6957 /**
6958 * GCM mode MAC calculation
6959 * @param {number} x0 - 128-bit input block vector
6960 * @param {number} x1 - 128-bit input block vector
6961 * @param {number} x2 - 128-bit input block vector
6962 * @param {number} x3 - 128-bit input block vector
6963 */
6964 function _gcm_mac(x0, x1, x2, x3) {
6965 x0 = x0 | 0;
6966 x1 = x1 | 0;
6967 x2 = x2 | 0;
6968 x3 = x3 | 0;
6969
6970 var y0 = 0, y1 = 0, y2 = 0, y3 = 0,
6971 z0 = 0, z1 = 0, z2 = 0, z3 = 0,
6972 i = 0, c = 0;
6973
6974 x0 = x0 ^ I0,
6975 x1 = x1 ^ I1,
6976 x2 = x2 ^ I2,
6977 x3 = x3 ^ I3;
6978
6979 y0 = H0 | 0,
6980 y1 = H1 | 0,
6981 y2 = H2 | 0,
6982 y3 = H3 | 0;
6983
6984 for (; (i | 0) < 128; i = (i + 1) | 0) {
6985 if (y0 >>> 31) {
6986 z0 = z0 ^ x0,
6987 z1 = z1 ^ x1,
6988 z2 = z2 ^ x2,
6989 z3 = z3 ^ x3;
6990 }
6991
6992 y0 = (y0 << 1) | (y1 >>> 31),
6993 y1 = (y1 << 1) | (y2 >>> 31),
6994 y2 = (y2 << 1) | (y3 >>> 31),
6995 y3 = (y3 << 1);
6996
6997 c = x3 & 1;
6998
6999 x3 = (x3 >>> 1) | (x2 << 31),
7000 x2 = (x2 >>> 1) | (x1 << 31),
7001 x1 = (x1 >>> 1) | (x0 << 31),
7002 x0 = (x0 >>> 1);
7003
7004 if (c) x0 = x0 ^ 0xe1000000;
7005 }
7006
7007 I0 = z0,
7008 I1 = z1,
7009 I2 = z2,
7010 I3 = z3;
7011 }
7012
7013 /**
7014 * Set the internal rounds number.
7015 * @instance
7016 * @memberof AES_asm
7017 * @param {number} r - number if inner AES rounds
7018 */
7019 function set_rounds(r) {
7020 r = r | 0;
7021 R = r;
7022 }
7023
7024 /**
7025 * Populate the internal state of the module.
7026 * @instance
7027 * @memberof AES_asm
7028 * @param {number} s0 - state vector
7029 * @param {number} s1 - state vector
7030 * @param {number} s2 - state vector
7031 * @param {number} s3 - state vector
7032 */
7033 function set_state(s0, s1, s2, s3) {
7034 s0 = s0 | 0;
7035 s1 = s1 | 0;
7036 s2 = s2 | 0;
7037 s3 = s3 | 0;
7038
7039 S0 = s0,
7040 S1 = s1,
7041 S2 = s2,
7042 S3 = s3;
7043 }
7044
7045 /**
7046 * Populate the internal iv of the module.
7047 * @instance
7048 * @memberof AES_asm
7049 * @param {number} i0 - iv vector
7050 * @param {number} i1 - iv vector
7051 * @param {number} i2 - iv vector
7052 * @param {number} i3 - iv vector
7053 */
7054 function set_iv(i0, i1, i2, i3) {
7055 i0 = i0 | 0;
7056 i1 = i1 | 0;
7057 i2 = i2 | 0;
7058 i3 = i3 | 0;
7059
7060 I0 = i0,
7061 I1 = i1,
7062 I2 = i2,
7063 I3 = i3;
7064 }
7065
7066 /**
7067 * Set nonce for CTR-family modes.
7068 * @instance
7069 * @memberof AES_asm
7070 * @param {number} n0 - nonce vector
7071 * @param {number} n1 - nonce vector
7072 * @param {number} n2 - nonce vector
7073 * @param {number} n3 - nonce vector
7074 */
7075 function set_nonce(n0, n1, n2, n3) {
7076 n0 = n0 | 0;
7077 n1 = n1 | 0;
7078 n2 = n2 | 0;
7079 n3 = n3 | 0;
7080
7081 N0 = n0,
7082 N1 = n1,
7083 N2 = n2,
7084 N3 = n3;
7085 }
7086
7087 /**
7088 * Set counter mask for CTR-family modes.
7089 * @instance
7090 * @memberof AES_asm
7091 * @param {number} m0 - counter mask vector
7092 * @param {number} m1 - counter mask vector
7093 * @param {number} m2 - counter mask vector
7094 * @param {number} m3 - counter mask vector
7095 */
7096 function set_mask(m0, m1, m2, m3) {
7097 m0 = m0 | 0;
7098 m1 = m1 | 0;
7099 m2 = m2 | 0;
7100 m3 = m3 | 0;
7101
7102 M0 = m0,
7103 M1 = m1,
7104 M2 = m2,
7105 M3 = m3;
7106 }
7107
7108 /**
7109 * Set counter for CTR-family modes.
7110 * @instance
7111 * @memberof AES_asm
7112 * @param {number} c0 - counter vector
7113 * @param {number} c1 - counter vector
7114 * @param {number} c2 - counter vector
7115 * @param {number} c3 - counter vector
7116 */
7117 function set_counter(c0, c1, c2, c3) {
7118 c0 = c0 | 0;
7119 c1 = c1 | 0;
7120 c2 = c2 | 0;
7121 c3 = c3 | 0;
7122
7123 N3 = (~M3 & N3) | M3 & c3,
7124 N2 = (~M2 & N2) | M2 & c2,
7125 N1 = (~M1 & N1) | M1 & c1,
7126 N0 = (~M0 & N0) | M0 & c0;
7127 }
7128
7129 /**
7130 * Store the internal state vector into the heap.
7131 * @instance
7132 * @memberof AES_asm
7133 * @param {number} pos - offset where to put the data
7134 * @return {number} The number of bytes have been written into the heap, always 16.
7135 */
7136 function get_state(pos) {
7137 pos = pos | 0;
7138
7139 if (pos & 15) return -1;
7140
7141 DATA[pos | 0] = S0 >>> 24,
7142 DATA[pos | 1] = S0 >>> 16 & 255,
7143 DATA[pos | 2] = S0 >>> 8 & 255,
7144 DATA[pos | 3] = S0 & 255,
7145 DATA[pos | 4] = S1 >>> 24,
7146 DATA[pos | 5] = S1 >>> 16 & 255,
7147 DATA[pos | 6] = S1 >>> 8 & 255,
7148 DATA[pos | 7] = S1 & 255,
7149 DATA[pos | 8] = S2 >>> 24,
7150 DATA[pos | 9] = S2 >>> 16 & 255,
7151 DATA[pos | 10] = S2 >>> 8 & 255,
7152 DATA[pos | 11] = S2 & 255,
7153 DATA[pos | 12] = S3 >>> 24,
7154 DATA[pos | 13] = S3 >>> 16 & 255,
7155 DATA[pos | 14] = S3 >>> 8 & 255,
7156 DATA[pos | 15] = S3 & 255;
7157
7158 return 16;
7159 }
7160
7161 /**
7162 * Store the internal iv vector into the heap.
7163 * @instance
7164 * @memberof AES_asm
7165 * @param {number} pos - offset where to put the data
7166 * @return {number} The number of bytes have been written into the heap, always 16.
7167 */
7168 function get_iv(pos) {
7169 pos = pos | 0;
7170
7171 if (pos & 15) return -1;
7172
7173 DATA[pos | 0] = I0 >>> 24,
7174 DATA[pos | 1] = I0 >>> 16 & 255,
7175 DATA[pos | 2] = I0 >>> 8 & 255,
7176 DATA[pos | 3] = I0 & 255,
7177 DATA[pos | 4] = I1 >>> 24,
7178 DATA[pos | 5] = I1 >>> 16 & 255,
7179 DATA[pos | 6] = I1 >>> 8 & 255,
7180 DATA[pos | 7] = I1 & 255,
7181 DATA[pos | 8] = I2 >>> 24,
7182 DATA[pos | 9] = I2 >>> 16 & 255,
7183 DATA[pos | 10] = I2 >>> 8 & 255,
7184 DATA[pos | 11] = I2 & 255,
7185 DATA[pos | 12] = I3 >>> 24,
7186 DATA[pos | 13] = I3 >>> 16 & 255,
7187 DATA[pos | 14] = I3 >>> 8 & 255,
7188 DATA[pos | 15] = I3 & 255;
7189
7190 return 16;
7191 }
7192
7193 /**
7194 * GCM initialization.
7195 * @instance
7196 * @memberof AES_asm
7197 */
7198 function gcm_init() {
7199 _ecb_enc(0, 0, 0, 0);
7200 H0 = S0,
7201 H1 = S1,
7202 H2 = S2,
7203 H3 = S3;
7204 }
7205
7206 /**
7207 * Perform ciphering operation on the supplied data.
7208 * @instance
7209 * @memberof AES_asm
7210 * @param {number} mode - block cipher mode (see {@link AES_asm} mode constants)
7211 * @param {number} pos - offset of the data being processed
7212 * @param {number} len - length of the data being processed
7213 * @return {number} Actual amount of data have been processed.
7214 */
7215 function cipher(mode, pos, len) {
7216 mode = mode | 0;
7217 pos = pos | 0;
7218 len = len | 0;
7219
7220 var ret = 0;
7221
7222 if (pos & 15) return -1;
7223
7224 while ((len | 0) >= 16) {
7225 _cipher_modes[mode & 7](
7226 DATA[pos | 0] << 24 | DATA[pos | 1] << 16 | DATA[pos | 2] << 8 | DATA[pos | 3],
7227 DATA[pos | 4] << 24 | DATA[pos | 5] << 16 | DATA[pos | 6] << 8 | DATA[pos | 7],
7228 DATA[pos | 8] << 24 | DATA[pos | 9] << 16 | DATA[pos | 10] << 8 | DATA[pos | 11],
7229 DATA[pos | 12] << 24 | DATA[pos | 13] << 16 | DATA[pos | 14] << 8 | DATA[pos | 15]
7230 );
7231
7232 DATA[pos | 0] = S0 >>> 24,
7233 DATA[pos | 1] = S0 >>> 16 & 255,
7234 DATA[pos | 2] = S0 >>> 8 & 255,
7235 DATA[pos | 3] = S0 & 255,
7236 DATA[pos | 4] = S1 >>> 24,
7237 DATA[pos | 5] = S1 >>> 16 & 255,
7238 DATA[pos | 6] = S1 >>> 8 & 255,
7239 DATA[pos | 7] = S1 & 255,
7240 DATA[pos | 8] = S2 >>> 24,
7241 DATA[pos | 9] = S2 >>> 16 & 255,
7242 DATA[pos | 10] = S2 >>> 8 & 255,
7243 DATA[pos | 11] = S2 & 255,
7244 DATA[pos | 12] = S3 >>> 24,
7245 DATA[pos | 13] = S3 >>> 16 & 255,
7246 DATA[pos | 14] = S3 >>> 8 & 255,
7247 DATA[pos | 15] = S3 & 255;
7248
7249 ret = (ret + 16) | 0,
7250 pos = (pos + 16) | 0,
7251 len = (len - 16) | 0;
7252 }
7253
7254 return ret | 0;
7255 }
7256
7257 /**
7258 * Calculates MAC of the supplied data.
7259 * @instance
7260 * @memberof AES_asm
7261 * @param {number} mode - block cipher mode (see {@link AES_asm} mode constants)
7262 * @param {number} pos - offset of the data being processed
7263 * @param {number} len - length of the data being processed
7264 * @return {number} Actual amount of data have been processed.
7265 */
7266 function mac(mode, pos, len) {
7267 mode = mode | 0;
7268 pos = pos | 0;
7269 len = len | 0;
7270
7271 var ret = 0;
7272
7273 if (pos & 15) return -1;
7274
7275 while ((len | 0) >= 16) {
7276 _mac_modes[mode & 1](
7277 DATA[pos | 0] << 24 | DATA[pos | 1] << 16 | DATA[pos | 2] << 8 | DATA[pos | 3],
7278 DATA[pos | 4] << 24 | DATA[pos | 5] << 16 | DATA[pos | 6] << 8 | DATA[pos | 7],
7279 DATA[pos | 8] << 24 | DATA[pos | 9] << 16 | DATA[pos | 10] << 8 | DATA[pos | 11],
7280 DATA[pos | 12] << 24 | DATA[pos | 13] << 16 | DATA[pos | 14] << 8 | DATA[pos | 15]
7281 );
7282
7283 ret = (ret + 16) | 0,
7284 pos = (pos + 16) | 0,
7285 len = (len - 16) | 0;
7286 }
7287
7288 return ret | 0;
7289 }
7290
7291 /**
7292 * AES cipher modes table (virual methods)
7293 */
7294 var _cipher_modes = [_ecb_enc, _ecb_dec, _cbc_enc, _cbc_dec, _cfb_enc, _cfb_dec, _ofb, _ctr];
7295
7296 /**
7297 * AES MAC modes table (virual methods)
7298 */
7299 var _mac_modes = [_cbc_enc, _gcm_mac];
7300
7301 /**
7302 * Asm.js module exports
7303 */
7304 return {
7305 set_rounds: set_rounds,
7306 set_state: set_state,
7307 set_iv: set_iv,
7308 set_nonce: set_nonce,
7309 set_mask: set_mask,
7310 set_counter: set_counter,
7311 get_state: get_state,
7312 get_iv: get_iv,
7313 gcm_init: gcm_init,
7314 cipher: cipher,
7315 mac: mac,
7316 };
7317 }(stdlib, foreign, buffer);
7318
7319 asm.set_key = set_key;
7320
7321 return asm;
7322 };
7323
7324 /**
7325 * AES enciphering mode constants
7326 * @enum {number}
7327 * @const
7328 */
7329 wrapper.ENC = {
7330 ECB: 0,
7331 CBC: 2,
7332 CFB: 4,
7333 OFB: 6,
7334 CTR: 7,
7335 },
7336
7337 /**
7338 * AES deciphering mode constants
7339 * @enum {number}
7340 * @const
7341 */
7342 wrapper.DEC = {
7343 ECB: 1,
7344 CBC: 3,
7345 CFB: 5,
7346 OFB: 6,
7347 CTR: 7,
7348 },
7349
7350 /**
7351 * AES MAC mode constants
7352 * @enum {number}
7353 * @const
7354 */
7355 wrapper.MAC = {
7356 CBC: 0,
7357 GCM: 1,
7358 };
7359
7360 /**
7361 * Heap data offset
7362 * @type {number}
7363 * @const
7364 */
7365 wrapper.HEAP_DATA = 0x4000;
7366
7367 return wrapper;
7368}();
7369
7370function is_bytes(a) {
7371 return a instanceof Uint8Array;
7372}
7373function _heap_init(heap, heapSize) {
7374 const size = heap ? heap.byteLength : heapSize || 65536;
7375 if (size & 0xfff || size <= 0)
7376 throw new Error('heap size must be a positive integer and a multiple of 4096');
7377 heap = heap || new Uint8Array(new ArrayBuffer(size));
7378 return heap;
7379}
7380function _heap_write(heap, hpos, data, dpos, dlen) {
7381 const hlen = heap.length - hpos;
7382 const wlen = hlen < dlen ? hlen : dlen;
7383 heap.set(data.subarray(dpos, dpos + wlen), hpos);
7384 return wlen;
7385}
7386function joinBytes(...arg) {
7387 const totalLenght = arg.reduce((sum, curr) => sum + curr.length, 0);
7388 const ret = new Uint8Array(totalLenght);
7389 let cursor = 0;
7390 for (let i = 0; i < arg.length; i++) {
7391 ret.set(arg[i], cursor);
7392 cursor += arg[i].length;
7393 }
7394 return ret;
7395}
7396
7397class IllegalStateError extends Error {
7398 constructor(...args) {
7399 super(...args);
7400 }
7401}
7402class IllegalArgumentError extends Error {
7403 constructor(...args) {
7404 super(...args);
7405 }
7406}
7407class SecurityError extends Error {
7408 constructor(...args) {
7409 super(...args);
7410 }
7411}
7412
7413const heap_pool = [];
7414const asm_pool = [];
7415class AES {
7416 constructor(key, iv, padding = true, mode, heap, asm) {
7417 this.pos = 0;
7418 this.len = 0;
7419 this.mode = mode;
7420 // The AES object state
7421 this.pos = 0;
7422 this.len = 0;
7423 this.key = key;
7424 this.iv = iv;
7425 this.padding = padding;
7426 // The AES "worker"
7427 this.acquire_asm(heap, asm);
7428 }
7429 acquire_asm(heap, asm) {
7430 if (this.heap === undefined || this.asm === undefined) {
7431 this.heap = heap || heap_pool.pop() || _heap_init().subarray(AES_asm.HEAP_DATA);
7432 this.asm = asm || asm_pool.pop() || new AES_asm(null, this.heap.buffer);
7433 this.reset(this.key, this.iv);
7434 }
7435 return { heap: this.heap, asm: this.asm };
7436 }
7437 release_asm() {
7438 if (this.heap !== undefined && this.asm !== undefined) {
7439 heap_pool.push(this.heap);
7440 asm_pool.push(this.asm);
7441 }
7442 this.heap = undefined;
7443 this.asm = undefined;
7444 }
7445 reset(key, iv) {
7446 const { asm } = this.acquire_asm();
7447 // Key
7448 const keylen = key.length;
7449 if (keylen !== 16 && keylen !== 24 && keylen !== 32)
7450 throw new IllegalArgumentError('illegal key size');
7451 const keyview = new DataView(key.buffer, key.byteOffset, key.byteLength);
7452 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);
7453 // IV
7454 if (iv !== undefined) {
7455 if (iv.length !== 16)
7456 throw new IllegalArgumentError('illegal iv size');
7457 let ivview = new DataView(iv.buffer, iv.byteOffset, iv.byteLength);
7458 asm.set_iv(ivview.getUint32(0), ivview.getUint32(4), ivview.getUint32(8), ivview.getUint32(12));
7459 }
7460 else {
7461 asm.set_iv(0, 0, 0, 0);
7462 }
7463 }
7464 AES_Encrypt_process(data) {
7465 if (!is_bytes(data))
7466 throw new TypeError("data isn't of expected type");
7467 let { heap, asm } = this.acquire_asm();
7468 let amode = AES_asm.ENC[this.mode];
7469 let hpos = AES_asm.HEAP_DATA;
7470 let pos = this.pos;
7471 let len = this.len;
7472 let dpos = 0;
7473 let dlen = data.length || 0;
7474 let rpos = 0;
7475 let rlen = (len + dlen) & -16;
7476 let wlen = 0;
7477 let result = new Uint8Array(rlen);
7478 while (dlen > 0) {
7479 wlen = _heap_write(heap, pos + len, data, dpos, dlen);
7480 len += wlen;
7481 dpos += wlen;
7482 dlen -= wlen;
7483 wlen = asm.cipher(amode, hpos + pos, len);
7484 if (wlen)
7485 result.set(heap.subarray(pos, pos + wlen), rpos);
7486 rpos += wlen;
7487 if (wlen < len) {
7488 pos += wlen;
7489 len -= wlen;
7490 }
7491 else {
7492 pos = 0;
7493 len = 0;
7494 }
7495 }
7496 this.pos = pos;
7497 this.len = len;
7498 return result;
7499 }
7500 AES_Encrypt_finish() {
7501 let { heap, asm } = this.acquire_asm();
7502 let amode = AES_asm.ENC[this.mode];
7503 let hpos = AES_asm.HEAP_DATA;
7504 let pos = this.pos;
7505 let len = this.len;
7506 let plen = 16 - (len % 16);
7507 let rlen = len;
7508 if (this.hasOwnProperty('padding')) {
7509 if (this.padding) {
7510 for (let p = 0; p < plen; ++p) {
7511 heap[pos + len + p] = plen;
7512 }
7513 len += plen;
7514 rlen = len;
7515 }
7516 else if (len % 16) {
7517 throw new IllegalArgumentError('data length must be a multiple of the block size');
7518 }
7519 }
7520 else {
7521 len += plen;
7522 }
7523 const result = new Uint8Array(rlen);
7524 if (len)
7525 asm.cipher(amode, hpos + pos, len);
7526 if (rlen)
7527 result.set(heap.subarray(pos, pos + rlen));
7528 this.pos = 0;
7529 this.len = 0;
7530 this.release_asm();
7531 return result;
7532 }
7533 AES_Decrypt_process(data) {
7534 if (!is_bytes(data))
7535 throw new TypeError("data isn't of expected type");
7536 let { heap, asm } = this.acquire_asm();
7537 let amode = AES_asm.DEC[this.mode];
7538 let hpos = AES_asm.HEAP_DATA;
7539 let pos = this.pos;
7540 let len = this.len;
7541 let dpos = 0;
7542 let dlen = data.length || 0;
7543 let rpos = 0;
7544 let rlen = (len + dlen) & -16;
7545 let plen = 0;
7546 let wlen = 0;
7547 if (this.padding) {
7548 plen = len + dlen - rlen || 16;
7549 rlen -= plen;
7550 }
7551 const result = new Uint8Array(rlen);
7552 while (dlen > 0) {
7553 wlen = _heap_write(heap, pos + len, data, dpos, dlen);
7554 len += wlen;
7555 dpos += wlen;
7556 dlen -= wlen;
7557 wlen = asm.cipher(amode, hpos + pos, len - (!dlen ? plen : 0));
7558 if (wlen)
7559 result.set(heap.subarray(pos, pos + wlen), rpos);
7560 rpos += wlen;
7561 if (wlen < len) {
7562 pos += wlen;
7563 len -= wlen;
7564 }
7565 else {
7566 pos = 0;
7567 len = 0;
7568 }
7569 }
7570 this.pos = pos;
7571 this.len = len;
7572 return result;
7573 }
7574 AES_Decrypt_finish() {
7575 let { heap, asm } = this.acquire_asm();
7576 let amode = AES_asm.DEC[this.mode];
7577 let hpos = AES_asm.HEAP_DATA;
7578 let pos = this.pos;
7579 let len = this.len;
7580 let rlen = len;
7581 if (len > 0) {
7582 if (len % 16) {
7583 if (this.hasOwnProperty('padding')) {
7584 throw new IllegalArgumentError('data length must be a multiple of the block size');
7585 }
7586 else {
7587 len += 16 - (len % 16);
7588 }
7589 }
7590 asm.cipher(amode, hpos + pos, len);
7591 if (this.hasOwnProperty('padding') && this.padding) {
7592 let pad = heap[pos + rlen - 1];
7593 if (pad < 1 || pad > 16 || pad > rlen)
7594 throw new SecurityError('bad padding');
7595 let pcheck = 0;
7596 for (let i = pad; i > 1; i--)
7597 pcheck |= pad ^ heap[pos + rlen - i];
7598 if (pcheck)
7599 throw new SecurityError('bad padding');
7600 rlen -= pad;
7601 }
7602 }
7603 const result = new Uint8Array(rlen);
7604 if (rlen > 0) {
7605 result.set(heap.subarray(pos, pos + rlen));
7606 }
7607 this.pos = 0;
7608 this.len = 0;
7609 this.release_asm();
7610 return result;
7611 }
7612}
7613
7614class AES_ECB {
7615 static encrypt(data, key, padding = false) {
7616 return new AES_ECB(key, padding).encrypt(data);
7617 }
7618 static decrypt(data, key, padding = false) {
7619 return new AES_ECB(key, padding).decrypt(data);
7620 }
7621 constructor(key, padding = false, aes) {
7622 this.aes = aes ? aes : new AES(key, undefined, padding, 'ECB');
7623 }
7624 encrypt(data) {
7625 const r1 = this.aes.AES_Encrypt_process(data);
7626 const r2 = this.aes.AES_Encrypt_finish();
7627 return joinBytes(r1, r2);
7628 }
7629 decrypt(data) {
7630 const r1 = this.aes.AES_Decrypt_process(data);
7631 const r2 = this.aes.AES_Decrypt_finish();
7632 return joinBytes(r1, r2);
7633 }
7634}
7635
7636// TODO use webCrypto or nodeCrypto when possible.
7637function aes(length) {
7638 const C = function(key) {
7639 const aes_ecb = new AES_ECB(key);
7640
7641 this.encrypt = function(block) {
7642 return aes_ecb.encrypt(block);
7643 };
7644
7645 this.decrypt = function(block) {
7646 return aes_ecb.decrypt(block);
7647 };
7648 };
7649
7650 C.blockSize = C.prototype.blockSize = 16;
7651 C.keySize = C.prototype.keySize = length / 8;
7652
7653 return C;
7654}
7655
7656//Paul Tero, July 2001
7657//http://www.tero.co.uk/des/
7658//
7659//Optimised for performance with large blocks by Michael Hayworth, November 2001
7660//http://www.netdealing.com
7661//
7662// Modified by Recurity Labs GmbH
7663
7664//THIS SOFTWARE IS PROVIDED "AS IS" AND
7665//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7666//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7667//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
7668//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7669//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7670//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7671//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7672//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7673//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7674//SUCH DAMAGE.
7675
7676//des
7677//this takes the key, the message, and whether to encrypt or decrypt
7678
7679function des(keys, message, encrypt, mode, iv, padding) {
7680 //declaring this locally speeds things up a bit
7681 const spfunction1 = [
7682 0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400,
7683 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000,
7684 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4,
7685 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404,
7686 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400,
7687 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004
7688 ];
7689 const spfunction2 = [
7690 -0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0,
7691 -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020,
7692 -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000,
7693 -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000,
7694 -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0,
7695 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0,
7696 -0x7fef7fe0, 0x108000
7697 ];
7698 const spfunction3 = [
7699 0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008,
7700 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000,
7701 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000,
7702 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0,
7703 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208,
7704 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200
7705 ];
7706 const spfunction4 = [
7707 0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000,
7708 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080,
7709 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0,
7710 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001,
7711 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080
7712 ];
7713 const spfunction5 = [
7714 0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000,
7715 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000,
7716 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100,
7717 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100,
7718 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100,
7719 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0,
7720 0x40080000, 0x2080100, 0x40000100
7721 ];
7722 const spfunction6 = [
7723 0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000,
7724 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010,
7725 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000,
7726 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000,
7727 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000,
7728 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010
7729 ];
7730 const spfunction7 = [
7731 0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802,
7732 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002,
7733 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000,
7734 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000,
7735 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0,
7736 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002
7737 ];
7738 const spfunction8 = [
7739 0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000,
7740 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000,
7741 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040,
7742 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040,
7743 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000,
7744 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000
7745 ];
7746
7747 //create the 16 or 48 subkeys we will need
7748 let m = 0;
7749 let i;
7750 let j;
7751 let temp;
7752 let right1;
7753 let right2;
7754 let left;
7755 let right;
7756 let looping;
7757 let cbcleft;
7758 let cbcleft2;
7759 let cbcright;
7760 let cbcright2;
7761 let endloop;
7762 let loopinc;
7763 let len = message.length;
7764
7765 //set up the loops for single and triple des
7766 const iterations = keys.length === 32 ? 3 : 9; //single or triple des
7767 if (iterations === 3) {
7768 looping = encrypt ? [0, 32, 2] : [30, -2, -2];
7769 } else {
7770 looping = encrypt ? [0, 32, 2, 62, 30, -2, 64, 96, 2] : [94, 62, -2, 32, 64, 2, 30, -2, -2];
7771 }
7772
7773 //pad the message depending on the padding parameter
7774 //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt
7775 if (encrypt) {
7776 message = des_addPadding(message, padding);
7777 len = message.length;
7778 }
7779
7780 //store the result here
7781 let result = new Uint8Array(len);
7782 let k = 0;
7783
7784 if (mode === 1) { //CBC mode
7785 cbcleft = (iv[m++] << 24) | (iv[m++] << 16) | (iv[m++] << 8) | iv[m++];
7786 cbcright = (iv[m++] << 24) | (iv[m++] << 16) | (iv[m++] << 8) | iv[m++];
7787 m = 0;
7788 }
7789
7790 //loop through each 64 bit chunk of the message
7791 while (m < len) {
7792 left = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
7793 right = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
7794
7795 //for Cipher Block Chaining mode, xor the message with the previous result
7796 if (mode === 1) {
7797 if (encrypt) {
7798 left ^= cbcleft;
7799 right ^= cbcright;
7800 } else {
7801 cbcleft2 = cbcleft;
7802 cbcright2 = cbcright;
7803 cbcleft = left;
7804 cbcright = right;
7805 }
7806 }
7807
7808 //first each 64 but chunk of the message must be permuted according to IP
7809 temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
7810 right ^= temp;
7811 left ^= (temp << 4);
7812 temp = ((left >>> 16) ^ right) & 0x0000ffff;
7813 right ^= temp;
7814 left ^= (temp << 16);
7815 temp = ((right >>> 2) ^ left) & 0x33333333;
7816 left ^= temp;
7817 right ^= (temp << 2);
7818 temp = ((right >>> 8) ^ left) & 0x00ff00ff;
7819 left ^= temp;
7820 right ^= (temp << 8);
7821 temp = ((left >>> 1) ^ right) & 0x55555555;
7822 right ^= temp;
7823 left ^= (temp << 1);
7824
7825 left = ((left << 1) | (left >>> 31));
7826 right = ((right << 1) | (right >>> 31));
7827
7828 //do this either 1 or 3 times for each chunk of the message
7829 for (j = 0; j < iterations; j += 3) {
7830 endloop = looping[j + 1];
7831 loopinc = looping[j + 2];
7832 //now go through and perform the encryption or decryption
7833 for (i = looping[j]; i !== endloop; i += loopinc) { //for efficiency
7834 right1 = right ^ keys[i];
7835 right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
7836 //the result is attained by passing these bytes through the S selection functions
7837 temp = left;
7838 left = right;
7839 right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>>
7840 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) &
7841 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
7842 }
7843 temp = left;
7844 left = right;
7845 right = temp; //unreverse left and right
7846 } //for either 1 or 3 iterations
7847
7848 //move then each one bit to the right
7849 left = ((left >>> 1) | (left << 31));
7850 right = ((right >>> 1) | (right << 31));
7851
7852 //now perform IP-1, which is IP in the opposite direction
7853 temp = ((left >>> 1) ^ right) & 0x55555555;
7854 right ^= temp;
7855 left ^= (temp << 1);
7856 temp = ((right >>> 8) ^ left) & 0x00ff00ff;
7857 left ^= temp;
7858 right ^= (temp << 8);
7859 temp = ((right >>> 2) ^ left) & 0x33333333;
7860 left ^= temp;
7861 right ^= (temp << 2);
7862 temp = ((left >>> 16) ^ right) & 0x0000ffff;
7863 right ^= temp;
7864 left ^= (temp << 16);
7865 temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
7866 right ^= temp;
7867 left ^= (temp << 4);
7868
7869 //for Cipher Block Chaining mode, xor the message with the previous result
7870 if (mode === 1) {
7871 if (encrypt) {
7872 cbcleft = left;
7873 cbcright = right;
7874 } else {
7875 left ^= cbcleft2;
7876 right ^= cbcright2;
7877 }
7878 }
7879
7880 result[k++] = (left >>> 24);
7881 result[k++] = ((left >>> 16) & 0xff);
7882 result[k++] = ((left >>> 8) & 0xff);
7883 result[k++] = (left & 0xff);
7884 result[k++] = (right >>> 24);
7885 result[k++] = ((right >>> 16) & 0xff);
7886 result[k++] = ((right >>> 8) & 0xff);
7887 result[k++] = (right & 0xff);
7888 } //for every 8 characters, or 64 bits in the message
7889
7890 //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt
7891 if (!encrypt) {
7892 result = des_removePadding(result, padding);
7893 }
7894
7895 return result;
7896} //end of des
7897
7898
7899//des_createKeys
7900//this takes as input a 64 bit key (even though only 56 bits are used)
7901//as an array of 2 integers, and returns 16 48 bit keys
7902
7903function des_createKeys(key) {
7904 //declaring this locally speeds things up a bit
7905 const pc2bytes0 = [
7906 0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204,
7907 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204
7908 ];
7909 const pc2bytes1 = [
7910 0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100,
7911 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101
7912 ];
7913 const pc2bytes2 = [
7914 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808,
7915 0x1000000, 0x1000008, 0x1000800, 0x1000808
7916 ];
7917 const pc2bytes3 = [
7918 0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000,
7919 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000
7920 ];
7921 const pc2bytes4 = [
7922 0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000,
7923 0x41000, 0x1010, 0x41010
7924 ];
7925 const pc2bytes5 = [
7926 0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420,
7927 0x2000000, 0x2000400, 0x2000020, 0x2000420
7928 ];
7929 const pc2bytes6 = [
7930 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000,
7931 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002
7932 ];
7933 const pc2bytes7 = [
7934 0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000,
7935 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800
7936 ];
7937 const pc2bytes8 = [
7938 0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000,
7939 0x2000002, 0x2040002, 0x2000002, 0x2040002
7940 ];
7941 const pc2bytes9 = [
7942 0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408,
7943 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408
7944 ];
7945 const pc2bytes10 = [
7946 0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020,
7947 0x102000, 0x102020, 0x102000, 0x102020
7948 ];
7949 const pc2bytes11 = [
7950 0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000,
7951 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200
7952 ];
7953 const pc2bytes12 = [
7954 0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010,
7955 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010
7956 ];
7957 const pc2bytes13 = [0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105];
7958
7959 //how many iterations (1 for des, 3 for triple des)
7960 const iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
7961 //stores the return keys
7962 const keys = new Array(32 * iterations);
7963 //now define the left shifts which need to be done
7964 const shifts = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0];
7965 //other variables
7966 let lefttemp;
7967 let righttemp;
7968 let m = 0;
7969 let n = 0;
7970 let temp;
7971
7972 for (let j = 0; j < iterations; j++) { //either 1 or 3 iterations
7973 let left = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
7974 let right = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
7975
7976 temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
7977 right ^= temp;
7978 left ^= (temp << 4);
7979 temp = ((right >>> -16) ^ left) & 0x0000ffff;
7980 left ^= temp;
7981 right ^= (temp << -16);
7982 temp = ((left >>> 2) ^ right) & 0x33333333;
7983 right ^= temp;
7984 left ^= (temp << 2);
7985 temp = ((right >>> -16) ^ left) & 0x0000ffff;
7986 left ^= temp;
7987 right ^= (temp << -16);
7988 temp = ((left >>> 1) ^ right) & 0x55555555;
7989 right ^= temp;
7990 left ^= (temp << 1);
7991 temp = ((right >>> 8) ^ left) & 0x00ff00ff;
7992 left ^= temp;
7993 right ^= (temp << 8);
7994 temp = ((left >>> 1) ^ right) & 0x55555555;
7995 right ^= temp;
7996 left ^= (temp << 1);
7997
7998 //the right side needs to be shifted and to get the last four bits of the left side
7999 temp = (left << 8) | ((right >>> 20) & 0x000000f0);
8000 //left needs to be put upside down
8001 left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
8002 right = temp;
8003
8004 //now go through and perform these shifts on the left and right keys
8005 for (let i = 0; i < shifts.length; i++) {
8006 //shift the keys either one or two bits to the left
8007 if (shifts[i]) {
8008 left = (left << 2) | (left >>> 26);
8009 right = (right << 2) | (right >>> 26);
8010 } else {
8011 left = (left << 1) | (left >>> 27);
8012 right = (right << 1) | (right >>> 27);
8013 }
8014 left &= -0xf;
8015 right &= -0xf;
8016
8017 //now apply PC-2, in such a way that E is easier when encrypting or decrypting
8018 //this conversion will look like PC-2 except only the last 6 bits of each byte are used
8019 //rather than 48 consecutive bits and the order of lines will be according to
8020 //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
8021 lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(
8022 left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) &
8023 0xf];
8024 righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] |
8025 pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] |
8026 pc2bytes13[(right >>> 4) & 0xf];
8027 temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
8028 keys[n++] = lefttemp ^ temp;
8029 keys[n++] = righttemp ^ (temp << 16);
8030 }
8031 } //for each iterations
8032 //return the keys we've created
8033 return keys;
8034} //end of des_createKeys
8035
8036
8037function des_addPadding(message, padding) {
8038 const padLength = 8 - (message.length % 8);
8039
8040 let pad;
8041 if (padding === 2 && (padLength < 8)) { //pad the message with spaces
8042 pad = " ".charCodeAt(0);
8043 } else if (padding === 1) { //PKCS7 padding
8044 pad = padLength;
8045 } else if (!padding && (padLength < 8)) { //pad the message out with null bytes
8046 pad = 0;
8047 } else if (padLength === 8) {
8048 return message;
8049 } else {
8050 throw new Error('des: invalid padding');
8051 }
8052
8053 const paddedMessage = new Uint8Array(message.length + padLength);
8054 for (let i = 0; i < message.length; i++) {
8055 paddedMessage[i] = message[i];
8056 }
8057 for (let j = 0; j < padLength; j++) {
8058 paddedMessage[message.length + j] = pad;
8059 }
8060
8061 return paddedMessage;
8062}
8063
8064function des_removePadding(message, padding) {
8065 let padLength = null;
8066 let pad;
8067 if (padding === 2) { // space padded
8068 pad = " ".charCodeAt(0);
8069 } else if (padding === 1) { // PKCS7
8070 padLength = message[message.length - 1];
8071 } else if (!padding) { // null padding
8072 pad = 0;
8073 } else {
8074 throw new Error('des: invalid padding');
8075 }
8076
8077 if (!padLength) {
8078 padLength = 1;
8079 while (message[message.length - padLength] === pad) {
8080 padLength++;
8081 }
8082 padLength--;
8083 }
8084
8085 return message.subarray(0, message.length - padLength);
8086}
8087
8088// added by Recurity Labs
8089
8090function TripleDES(key) {
8091 this.key = [];
8092
8093 for (let i = 0; i < 3; i++) {
8094 this.key.push(new Uint8Array(key.subarray(i * 8, (i * 8) + 8)));
8095 }
8096
8097 this.encrypt = function(block) {
8098 return des(
8099 des_createKeys(this.key[2]),
8100 des(
8101 des_createKeys(this.key[1]),
8102 des(
8103 des_createKeys(this.key[0]),
8104 block, true, 0, null, null
8105 ),
8106 false, 0, null, null
8107 ), true, 0, null, null
8108 );
8109 };
8110}
8111
8112TripleDES.keySize = TripleDES.prototype.keySize = 24;
8113TripleDES.blockSize = TripleDES.prototype.blockSize = 8;
8114
8115// This is "original" DES
8116
8117function DES(key) {
8118 this.key = key;
8119
8120 this.encrypt = function(block, padding) {
8121 const keys = des_createKeys(this.key);
8122 return des(keys, block, true, 0, null, padding);
8123 };
8124
8125 this.decrypt = function(block, padding) {
8126 const keys = des_createKeys(this.key);
8127 return des(keys, block, false, 0, null, padding);
8128 };
8129}
8130
8131// Use of this source code is governed by a BSD-style
8132// license that can be found in the LICENSE file.
8133
8134// Copyright 2010 pjacobs@xeekr.com . All rights reserved.
8135
8136// Modified by Recurity Labs GmbH
8137
8138// fixed/modified by Herbert Hanewinkel, www.haneWIN.de
8139// check www.haneWIN.de for the latest version
8140
8141// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144.
8142// CAST-128 is a common OpenPGP cipher.
8143
8144
8145// CAST5 constructor
8146
8147function OpenpgpSymencCast5() {
8148 this.BlockSize = 8;
8149 this.KeySize = 16;
8150
8151 this.setKey = function(key) {
8152 this.masking = new Array(16);
8153 this.rotate = new Array(16);
8154
8155 this.reset();
8156
8157 if (key.length === this.KeySize) {
8158 this.keySchedule(key);
8159 } else {
8160 throw new Error('CAST-128: keys must be 16 bytes');
8161 }
8162 return true;
8163 };
8164
8165 this.reset = function() {
8166 for (let i = 0; i < 16; i++) {
8167 this.masking[i] = 0;
8168 this.rotate[i] = 0;
8169 }
8170 };
8171
8172 this.getBlockSize = function() {
8173 return this.BlockSize;
8174 };
8175
8176 this.encrypt = function(src) {
8177 const dst = new Array(src.length);
8178
8179 for (let i = 0; i < src.length; i += 8) {
8180 let l = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
8181 let r = (src[i + 4] << 24) | (src[i + 5] << 16) | (src[i + 6] << 8) | src[i + 7];
8182 let t;
8183
8184 t = r;
8185 r = l ^ f1(r, this.masking[0], this.rotate[0]);
8186 l = t;
8187 t = r;
8188 r = l ^ f2(r, this.masking[1], this.rotate[1]);
8189 l = t;
8190 t = r;
8191 r = l ^ f3(r, this.masking[2], this.rotate[2]);
8192 l = t;
8193 t = r;
8194 r = l ^ f1(r, this.masking[3], this.rotate[3]);
8195 l = t;
8196
8197 t = r;
8198 r = l ^ f2(r, this.masking[4], this.rotate[4]);
8199 l = t;
8200 t = r;
8201 r = l ^ f3(r, this.masking[5], this.rotate[5]);
8202 l = t;
8203 t = r;
8204 r = l ^ f1(r, this.masking[6], this.rotate[6]);
8205 l = t;
8206 t = r;
8207 r = l ^ f2(r, this.masking[7], this.rotate[7]);
8208 l = t;
8209
8210 t = r;
8211 r = l ^ f3(r, this.masking[8], this.rotate[8]);
8212 l = t;
8213 t = r;
8214 r = l ^ f1(r, this.masking[9], this.rotate[9]);
8215 l = t;
8216 t = r;
8217 r = l ^ f2(r, this.masking[10], this.rotate[10]);
8218 l = t;
8219 t = r;
8220 r = l ^ f3(r, this.masking[11], this.rotate[11]);
8221 l = t;
8222
8223 t = r;
8224 r = l ^ f1(r, this.masking[12], this.rotate[12]);
8225 l = t;
8226 t = r;
8227 r = l ^ f2(r, this.masking[13], this.rotate[13]);
8228 l = t;
8229 t = r;
8230 r = l ^ f3(r, this.masking[14], this.rotate[14]);
8231 l = t;
8232 t = r;
8233 r = l ^ f1(r, this.masking[15], this.rotate[15]);
8234 l = t;
8235
8236 dst[i] = (r >>> 24) & 255;
8237 dst[i + 1] = (r >>> 16) & 255;
8238 dst[i + 2] = (r >>> 8) & 255;
8239 dst[i + 3] = r & 255;
8240 dst[i + 4] = (l >>> 24) & 255;
8241 dst[i + 5] = (l >>> 16) & 255;
8242 dst[i + 6] = (l >>> 8) & 255;
8243 dst[i + 7] = l & 255;
8244 }
8245
8246 return dst;
8247 };
8248
8249 this.decrypt = function(src) {
8250 const dst = new Array(src.length);
8251
8252 for (let i = 0; i < src.length; i += 8) {
8253 let l = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
8254 let r = (src[i + 4] << 24) | (src[i + 5] << 16) | (src[i + 6] << 8) | src[i + 7];
8255 let t;
8256
8257 t = r;
8258 r = l ^ f1(r, this.masking[15], this.rotate[15]);
8259 l = t;
8260 t = r;
8261 r = l ^ f3(r, this.masking[14], this.rotate[14]);
8262 l = t;
8263 t = r;
8264 r = l ^ f2(r, this.masking[13], this.rotate[13]);
8265 l = t;
8266 t = r;
8267 r = l ^ f1(r, this.masking[12], this.rotate[12]);
8268 l = t;
8269
8270 t = r;
8271 r = l ^ f3(r, this.masking[11], this.rotate[11]);
8272 l = t;
8273 t = r;
8274 r = l ^ f2(r, this.masking[10], this.rotate[10]);
8275 l = t;
8276 t = r;
8277 r = l ^ f1(r, this.masking[9], this.rotate[9]);
8278 l = t;
8279 t = r;
8280 r = l ^ f3(r, this.masking[8], this.rotate[8]);
8281 l = t;
8282
8283 t = r;
8284 r = l ^ f2(r, this.masking[7], this.rotate[7]);
8285 l = t;
8286 t = r;
8287 r = l ^ f1(r, this.masking[6], this.rotate[6]);
8288 l = t;
8289 t = r;
8290 r = l ^ f3(r, this.masking[5], this.rotate[5]);
8291 l = t;
8292 t = r;
8293 r = l ^ f2(r, this.masking[4], this.rotate[4]);
8294 l = t;
8295
8296 t = r;
8297 r = l ^ f1(r, this.masking[3], this.rotate[3]);
8298 l = t;
8299 t = r;
8300 r = l ^ f3(r, this.masking[2], this.rotate[2]);
8301 l = t;
8302 t = r;
8303 r = l ^ f2(r, this.masking[1], this.rotate[1]);
8304 l = t;
8305 t = r;
8306 r = l ^ f1(r, this.masking[0], this.rotate[0]);
8307 l = t;
8308
8309 dst[i] = (r >>> 24) & 255;
8310 dst[i + 1] = (r >>> 16) & 255;
8311 dst[i + 2] = (r >>> 8) & 255;
8312 dst[i + 3] = r & 255;
8313 dst[i + 4] = (l >>> 24) & 255;
8314 dst[i + 5] = (l >> 16) & 255;
8315 dst[i + 6] = (l >> 8) & 255;
8316 dst[i + 7] = l & 255;
8317 }
8318
8319 return dst;
8320 };
8321 const scheduleA = new Array(4);
8322
8323 scheduleA[0] = new Array(4);
8324 scheduleA[0][0] = [4, 0, 0xd, 0xf, 0xc, 0xe, 0x8];
8325 scheduleA[0][1] = [5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa];
8326 scheduleA[0][2] = [6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9];
8327 scheduleA[0][3] = [7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb];
8328
8329 scheduleA[1] = new Array(4);
8330 scheduleA[1][0] = [0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0];
8331 scheduleA[1][1] = [1, 4, 0, 2, 1, 3, 16 + 2];
8332 scheduleA[1][2] = [2, 5, 7, 6, 5, 4, 16 + 1];
8333 scheduleA[1][3] = [3, 7, 0xa, 9, 0xb, 8, 16 + 3];
8334
8335 scheduleA[2] = new Array(4);
8336 scheduleA[2][0] = [4, 0, 0xd, 0xf, 0xc, 0xe, 8];
8337 scheduleA[2][1] = [5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa];
8338 scheduleA[2][2] = [6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9];
8339 scheduleA[2][3] = [7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb];
8340
8341
8342 scheduleA[3] = new Array(4);
8343 scheduleA[3][0] = [0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0];
8344 scheduleA[3][1] = [1, 4, 0, 2, 1, 3, 16 + 2];
8345 scheduleA[3][2] = [2, 5, 7, 6, 5, 4, 16 + 1];
8346 scheduleA[3][3] = [3, 7, 0xa, 9, 0xb, 8, 16 + 3];
8347
8348 const scheduleB = new Array(4);
8349
8350 scheduleB[0] = new Array(4);
8351 scheduleB[0][0] = [16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2];
8352 scheduleB[0][1] = [16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6];
8353 scheduleB[0][2] = [16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9];
8354 scheduleB[0][3] = [16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc];
8355
8356 scheduleB[1] = new Array(4);
8357 scheduleB[1][0] = [3, 2, 0xc, 0xd, 8];
8358 scheduleB[1][1] = [1, 0, 0xe, 0xf, 0xd];
8359 scheduleB[1][2] = [7, 6, 8, 9, 3];
8360 scheduleB[1][3] = [5, 4, 0xa, 0xb, 7];
8361
8362
8363 scheduleB[2] = new Array(4);
8364 scheduleB[2][0] = [16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9];
8365 scheduleB[2][1] = [16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc];
8366 scheduleB[2][2] = [16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2];
8367 scheduleB[2][3] = [16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6];
8368
8369
8370 scheduleB[3] = new Array(4);
8371 scheduleB[3][0] = [8, 9, 7, 6, 3];
8372 scheduleB[3][1] = [0xa, 0xb, 5, 4, 7];
8373 scheduleB[3][2] = [0xc, 0xd, 3, 2, 8];
8374 scheduleB[3][3] = [0xe, 0xf, 1, 0, 0xd];
8375
8376 // changed 'in' to 'inn' (in javascript 'in' is a reserved word)
8377 this.keySchedule = function(inn) {
8378 const t = new Array(8);
8379 const k = new Array(32);
8380
8381 let j;
8382
8383 for (let i = 0; i < 4; i++) {
8384 j = i * 4;
8385 t[i] = (inn[j] << 24) | (inn[j + 1] << 16) | (inn[j + 2] << 8) | inn[j + 3];
8386 }
8387
8388 const x = [6, 7, 4, 5];
8389 let ki = 0;
8390 let w;
8391
8392 for (let half = 0; half < 2; half++) {
8393 for (let round = 0; round < 4; round++) {
8394 for (j = 0; j < 4; j++) {
8395 const a = scheduleA[round][j];
8396 w = t[a[1]];
8397
8398 w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff];
8399 w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff];
8400 w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff];
8401 w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff];
8402 w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff];
8403 t[a[0]] = w;
8404 }
8405
8406 for (j = 0; j < 4; j++) {
8407 const b = scheduleB[round][j];
8408 w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff];
8409
8410 w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff];
8411 w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff];
8412 w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff];
8413 w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff];
8414 k[ki] = w;
8415 ki++;
8416 }
8417 }
8418 }
8419
8420 for (let i = 0; i < 16; i++) {
8421 this.masking[i] = k[i];
8422 this.rotate[i] = k[16 + i] & 0x1f;
8423 }
8424 };
8425
8426 // These are the three 'f' functions. See RFC 2144, section 2.2.
8427
8428 function f1(d, m, r) {
8429 const t = m + d;
8430 const I = (t << r) | (t >>> (32 - r));
8431 return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255];
8432 }
8433
8434 function f2(d, m, r) {
8435 const t = m ^ d;
8436 const I = (t << r) | (t >>> (32 - r));
8437 return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255];
8438 }
8439
8440 function f3(d, m, r) {
8441 const t = m - d;
8442 const I = (t << r) | (t >>> (32 - r));
8443 return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255];
8444 }
8445
8446 const sBox = new Array(8);
8447 sBox[0] = [
8448 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
8449 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
8450 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
8451 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
8452 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
8453 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
8454 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
8455 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
8456 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
8457 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
8458 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
8459 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
8460 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
8461 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
8462 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
8463 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
8464 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
8465 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
8466 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
8467 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
8468 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
8469 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
8470 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
8471 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
8472 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
8473 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
8474 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
8475 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
8476 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
8477 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
8478 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
8479 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
8480 ];
8481
8482 sBox[1] = [
8483 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
8484 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
8485 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
8486 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
8487 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
8488 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
8489 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
8490 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
8491 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
8492 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
8493 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
8494 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
8495 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
8496 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
8497 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
8498 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
8499 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
8500 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
8501 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
8502 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
8503 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
8504 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
8505 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
8506 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
8507 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
8508 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
8509 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
8510 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
8511 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
8512 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
8513 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
8514 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
8515 ];
8516
8517 sBox[2] = [
8518 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
8519 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
8520 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
8521 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
8522 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
8523 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
8524 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
8525 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
8526 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
8527 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
8528 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
8529 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
8530 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
8531 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
8532 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
8533 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
8534 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
8535 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
8536 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
8537 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
8538 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
8539 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
8540 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
8541 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
8542 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
8543 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
8544 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
8545 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
8546 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
8547 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
8548 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
8549 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
8550 ];
8551
8552 sBox[3] = [
8553 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
8554 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
8555 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
8556 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
8557 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
8558 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
8559 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
8560 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
8561 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
8562 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
8563 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
8564 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
8565 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
8566 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
8567 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
8568 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
8569 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
8570 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
8571 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
8572 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
8573 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
8574 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
8575 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
8576 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
8577 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
8578 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
8579 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
8580 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
8581 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
8582 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
8583 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
8584 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
8585 ];
8586
8587 sBox[4] = [
8588 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
8589 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
8590 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
8591 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
8592 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
8593 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
8594 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
8595 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
8596 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
8597 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
8598 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
8599 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
8600 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
8601 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
8602 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
8603 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
8604 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
8605 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
8606 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
8607 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
8608 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
8609 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
8610 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
8611 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
8612 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
8613 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
8614 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
8615 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
8616 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
8617 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
8618 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
8619 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
8620 ];
8621
8622 sBox[5] = [
8623 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
8624 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
8625 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
8626 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
8627 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
8628 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
8629 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
8630 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
8631 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
8632 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
8633 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
8634 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
8635 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
8636 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
8637 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
8638 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
8639 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
8640 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
8641 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
8642 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
8643 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
8644 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
8645 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
8646 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
8647 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
8648 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
8649 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
8650 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
8651 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
8652 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
8653 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
8654 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
8655 ];
8656
8657 sBox[6] = [
8658 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
8659 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
8660 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
8661 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
8662 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
8663 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
8664 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
8665 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
8666 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
8667 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
8668 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
8669 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
8670 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
8671 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
8672 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
8673 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
8674 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
8675 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
8676 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
8677 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
8678 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
8679 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
8680 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
8681 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
8682 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
8683 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
8684 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
8685 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
8686 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
8687 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
8688 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
8689 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
8690 ];
8691
8692 sBox[7] = [
8693 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
8694 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
8695 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
8696 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
8697 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
8698 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
8699 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
8700 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
8701 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
8702 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
8703 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
8704 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
8705 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
8706 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
8707 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
8708 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
8709 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
8710 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
8711 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
8712 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
8713 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
8714 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
8715 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
8716 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
8717 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
8718 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
8719 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
8720 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
8721 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
8722 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
8723 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
8724 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
8725 ];
8726}
8727
8728function Cast5(key) {
8729 this.cast5 = new OpenpgpSymencCast5();
8730 this.cast5.setKey(key);
8731
8732 this.encrypt = function(block) {
8733 return this.cast5.encrypt(block);
8734 };
8735}
8736
8737Cast5.blockSize = Cast5.prototype.blockSize = 8;
8738Cast5.keySize = Cast5.prototype.keySize = 16;
8739
8740/* eslint-disable no-mixed-operators, no-fallthrough */
8741
8742
8743/* Modified by Recurity Labs GmbH
8744 *
8745 * Cipher.js
8746 * A block-cipher algorithm implementation on JavaScript
8747 * See Cipher.readme.txt for further information.
8748 *
8749 * Copyright(c) 2009 Atsushi Oka [ http://oka.nu/ ]
8750 * This script file is distributed under the LGPL
8751 *
8752 * ACKNOWLEDGMENT
8753 *
8754 * The main subroutines are written by Michiel van Everdingen.
8755 *
8756 * Michiel van Everdingen
8757 * http://home.versatel.nl/MAvanEverdingen/index.html
8758 *
8759 * All rights for these routines are reserved to Michiel van Everdingen.
8760 *
8761 */
8762
8763////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8764//Math
8765////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8766
8767const MAXINT = 0xFFFFFFFF;
8768
8769function rotw(w, n) {
8770 return (w << n | w >>> (32 - n)) & MAXINT;
8771}
8772
8773function getW(a, i) {
8774 return a[i] | a[i + 1] << 8 | a[i + 2] << 16 | a[i + 3] << 24;
8775}
8776
8777function setW(a, i, w) {
8778 a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF);
8779}
8780
8781function getB(x, n) {
8782 return (x >>> (n * 8)) & 0xFF;
8783}
8784
8785// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8786// Twofish
8787// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8788
8789function createTwofish() {
8790 //
8791 let keyBytes = null;
8792 let dataBytes = null;
8793 let dataOffset = -1;
8794 // var dataLength = -1;
8795 // var idx2 = -1;
8796 //
8797
8798 let tfsKey = [];
8799 let tfsM = [
8800 [],
8801 [],
8802 [],
8803 []
8804 ];
8805
8806 function tfsInit(key) {
8807 keyBytes = key;
8808 let i;
8809 let a;
8810 let b;
8811 let c;
8812 let d;
8813 const meKey = [];
8814 const moKey = [];
8815 const inKey = [];
8816 let kLen;
8817 const sKey = [];
8818 let f01;
8819 let f5b;
8820 let fef;
8821
8822 const q0 = [
8823 [8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4],
8824 [2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5]
8825 ];
8826 const q1 = [
8827 [14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13],
8828 [1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8]
8829 ];
8830 const q2 = [
8831 [11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1],
8832 [4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15]
8833 ];
8834 const q3 = [
8835 [13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10],
8836 [11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10]
8837 ];
8838 const ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15];
8839 const ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7];
8840 const q = [
8841 [],
8842 []
8843 ];
8844 const m = [
8845 [],
8846 [],
8847 [],
8848 []
8849 ];
8850
8851 function ffm5b(x) {
8852 return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3];
8853 }
8854
8855 function ffmEf(x) {
8856 return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3];
8857 }
8858
8859 function mdsRem(p, q) {
8860 let i;
8861 let t;
8862 let u;
8863 for (i = 0; i < 8; i++) {
8864 t = q >>> 24;
8865 q = ((q << 8) & MAXINT) | p >>> 24;
8866 p = (p << 8) & MAXINT;
8867 u = t << 1;
8868 if (t & 128) {
8869 u ^= 333;
8870 }
8871 q ^= t ^ (u << 16);
8872 u ^= t >>> 1;
8873 if (t & 1) {
8874 u ^= 166;
8875 }
8876 q ^= u << 24 | u << 8;
8877 }
8878 return q;
8879 }
8880
8881 function qp(n, x) {
8882 const a = x >> 4;
8883 const b = x & 15;
8884 const c = q0[n][a ^ b];
8885 const d = q1[n][ror4[b] ^ ashx[a]];
8886 return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d];
8887 }
8888
8889 function hFun(x, key) {
8890 let a = getB(x, 0);
8891 let b = getB(x, 1);
8892 let c = getB(x, 2);
8893 let d = getB(x, 3);
8894 switch (kLen) {
8895 case 4:
8896 a = q[1][a] ^ getB(key[3], 0);
8897 b = q[0][b] ^ getB(key[3], 1);
8898 c = q[0][c] ^ getB(key[3], 2);
8899 d = q[1][d] ^ getB(key[3], 3);
8900 case 3:
8901 a = q[1][a] ^ getB(key[2], 0);
8902 b = q[1][b] ^ getB(key[2], 1);
8903 c = q[0][c] ^ getB(key[2], 2);
8904 d = q[0][d] ^ getB(key[2], 3);
8905 case 2:
8906 a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0);
8907 b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1);
8908 c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2);
8909 d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3);
8910 }
8911 return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d];
8912 }
8913
8914 keyBytes = keyBytes.slice(0, 32);
8915 i = keyBytes.length;
8916 while (i !== 16 && i !== 24 && i !== 32) {
8917 keyBytes[i++] = 0;
8918 }
8919
8920 for (i = 0; i < keyBytes.length; i += 4) {
8921 inKey[i >> 2] = getW(keyBytes, i);
8922 }
8923 for (i = 0; i < 256; i++) {
8924 q[0][i] = qp(0, i);
8925 q[1][i] = qp(1, i);
8926 }
8927 for (i = 0; i < 256; i++) {
8928 f01 = q[1][i];
8929 f5b = ffm5b(f01);
8930 fef = ffmEf(f01);
8931 m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24);
8932 m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24);
8933 f01 = q[0][i];
8934 f5b = ffm5b(f01);
8935 fef = ffmEf(f01);
8936 m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24);
8937 m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
8938 }
8939
8940 kLen = inKey.length / 2;
8941 for (i = 0; i < kLen; i++) {
8942 a = inKey[i + i];
8943 meKey[i] = a;
8944 b = inKey[i + i + 1];
8945 moKey[i] = b;
8946 sKey[kLen - i - 1] = mdsRem(a, b);
8947 }
8948 for (i = 0; i < 40; i += 2) {
8949 a = 0x1010101 * i;
8950 b = a + 0x1010101;
8951 a = hFun(a, meKey);
8952 b = rotw(hFun(b, moKey), 8);
8953 tfsKey[i] = (a + b) & MAXINT;
8954 tfsKey[i + 1] = rotw(a + 2 * b, 9);
8955 }
8956 for (i = 0; i < 256; i++) {
8957 a = b = c = d = i;
8958 switch (kLen) {
8959 case 4:
8960 a = q[1][a] ^ getB(sKey[3], 0);
8961 b = q[0][b] ^ getB(sKey[3], 1);
8962 c = q[0][c] ^ getB(sKey[3], 2);
8963 d = q[1][d] ^ getB(sKey[3], 3);
8964 case 3:
8965 a = q[1][a] ^ getB(sKey[2], 0);
8966 b = q[1][b] ^ getB(sKey[2], 1);
8967 c = q[0][c] ^ getB(sKey[2], 2);
8968 d = q[0][d] ^ getB(sKey[2], 3);
8969 case 2:
8970 tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)];
8971 tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)];
8972 tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] ^ getB(sKey[0], 2)];
8973 tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] ^ getB(sKey[0], 3)];
8974 }
8975 }
8976 }
8977
8978 function tfsG0(x) {
8979 return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] ^ tfsM[3][getB(x, 3)];
8980 }
8981
8982 function tfsG1(x) {
8983 return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] ^ tfsM[3][getB(x, 2)];
8984 }
8985
8986 function tfsFrnd(r, blk) {
8987 let a = tfsG0(blk[0]);
8988 let b = tfsG1(blk[1]);
8989 blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31);
8990 blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT;
8991 a = tfsG0(blk[2]);
8992 b = tfsG1(blk[3]);
8993 blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31);
8994 blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT;
8995 }
8996
8997 function tfsIrnd(i, blk) {
8998 let a = tfsG0(blk[0]);
8999 let b = tfsG1(blk[1]);
9000 blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT;
9001 blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31);
9002 a = tfsG0(blk[2]);
9003 b = tfsG1(blk[3]);
9004 blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT;
9005 blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31);
9006 }
9007
9008 function tfsClose() {
9009 tfsKey = [];
9010 tfsM = [
9011 [],
9012 [],
9013 [],
9014 []
9015 ];
9016 }
9017
9018 function tfsEncrypt(data, offset) {
9019 dataBytes = data;
9020 dataOffset = offset;
9021 const blk = [getW(dataBytes, dataOffset) ^ tfsKey[0],
9022 getW(dataBytes, dataOffset + 4) ^ tfsKey[1],
9023 getW(dataBytes, dataOffset + 8) ^ tfsKey[2],
9024 getW(dataBytes, dataOffset + 12) ^ tfsKey[3]];
9025 for (let j = 0; j < 8; j++) {
9026 tfsFrnd(j, blk);
9027 }
9028 setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]);
9029 setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]);
9030 setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]);
9031 setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]);
9032 dataOffset += 16;
9033 return dataBytes;
9034 }
9035
9036 function tfsDecrypt(data, offset) {
9037 dataBytes = data;
9038 dataOffset = offset;
9039 const blk = [getW(dataBytes, dataOffset) ^ tfsKey[4],
9040 getW(dataBytes, dataOffset + 4) ^ tfsKey[5],
9041 getW(dataBytes, dataOffset + 8) ^ tfsKey[6],
9042 getW(dataBytes, dataOffset + 12) ^ tfsKey[7]];
9043 for (let j = 7; j >= 0; j--) {
9044 tfsIrnd(j, blk);
9045 }
9046 setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]);
9047 setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]);
9048 setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]);
9049 setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]);
9050 dataOffset += 16;
9051 }
9052
9053 // added by Recurity Labs
9054
9055 function tfsFinal() {
9056 return dataBytes;
9057 }
9058
9059 return {
9060 name: "twofish",
9061 blocksize: 128 / 8,
9062 open: tfsInit,
9063 close: tfsClose,
9064 encrypt: tfsEncrypt,
9065 decrypt: tfsDecrypt,
9066 // added by Recurity Labs
9067 finalize: tfsFinal
9068 };
9069}
9070
9071// added by Recurity Labs
9072
9073function TF(key) {
9074 this.tf = createTwofish();
9075 this.tf.open(Array.from(key), 0);
9076
9077 this.encrypt = function(block) {
9078 return this.tf.encrypt(Array.from(block), 0);
9079 };
9080}
9081
9082TF.keySize = TF.prototype.keySize = 32;
9083TF.blockSize = TF.prototype.blockSize = 16;
9084
9085/* Modified by Recurity Labs GmbH
9086 *
9087 * Originally written by nklein software (nklein.com)
9088 */
9089
9090/*
9091 * Javascript implementation based on Bruce Schneier's reference implementation.
9092 *
9093 *
9094 * The constructor doesn't do much of anything. It's just here
9095 * so we can start defining properties and methods and such.
9096 */
9097function Blowfish() {}
9098
9099/*
9100 * Declare the block size so that protocols know what size
9101 * Initialization Vector (IV) they will need.
9102 */
9103Blowfish.prototype.BLOCKSIZE = 8;
9104
9105/*
9106 * These are the default SBOXES.
9107 */
9108Blowfish.prototype.SBOXES = [
9109 [
9110 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
9111 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
9112 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
9113 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
9114 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
9115 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
9116 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
9117 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
9118 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
9119 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
9120 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
9121 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
9122 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
9123 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
9124 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
9125 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
9126 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
9127 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
9128 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
9129 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
9130 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
9131 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
9132 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
9133 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
9134 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
9135 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
9136 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
9137 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
9138 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
9139 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
9140 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
9141 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
9142 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
9143 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
9144 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
9145 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
9146 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
9147 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
9148 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
9149 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
9150 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
9151 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
9152 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
9153 ],
9154 [
9155 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
9156 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
9157 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
9158 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
9159 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
9160 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
9161 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
9162 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
9163 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
9164 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
9165 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
9166 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
9167 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
9168 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
9169 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
9170 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
9171 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
9172 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
9173 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
9174 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
9175 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
9176 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
9177 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
9178 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
9179 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
9180 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
9181 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
9182 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
9183 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
9184 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
9185 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
9186 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
9187 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
9188 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
9189 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
9190 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
9191 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
9192 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
9193 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
9194 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
9195 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
9196 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
9197 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
9198 ],
9199 [
9200 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
9201 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
9202 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
9203 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
9204 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
9205 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
9206 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
9207 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
9208 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
9209 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
9210 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
9211 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
9212 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
9213 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
9214 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
9215 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
9216 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
9217 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
9218 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
9219 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
9220 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
9221 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
9222 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
9223 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
9224 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
9225 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
9226 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
9227 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
9228 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
9229 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
9230 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
9231 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
9232 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
9233 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
9234 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
9235 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
9236 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
9237 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
9238 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
9239 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
9240 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
9241 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
9242 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
9243 ],
9244 [
9245 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
9246 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
9247 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
9248 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
9249 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
9250 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
9251 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
9252 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
9253 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
9254 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
9255 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
9256 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
9257 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
9258 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
9259 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
9260 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
9261 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
9262 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
9263 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
9264 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
9265 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
9266 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
9267 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
9268 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
9269 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
9270 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
9271 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
9272 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
9273 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
9274 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
9275 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
9276 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
9277 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
9278 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
9279 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
9280 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
9281 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
9282 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
9283 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
9284 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
9285 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
9286 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
9287 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
9288 ]
9289];
9290
9291//*
9292//* This is the default PARRAY
9293//*
9294Blowfish.prototype.PARRAY = [
9295 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
9296 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
9297 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
9298];
9299
9300//*
9301//* This is the number of rounds the cipher will go
9302//*
9303Blowfish.prototype.NN = 16;
9304
9305//*
9306//* This function is needed to get rid of problems
9307//* with the high-bit getting set. If we don't do
9308//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not
9309//* equal to ( bb & 0x00FFFFFFFF ) even when they
9310//* agree bit-for-bit for the first 32 bits.
9311//*
9312Blowfish.prototype._clean = function(xx) {
9313 if (xx < 0) {
9314 const yy = xx & 0x7FFFFFFF;
9315 xx = yy + 0x80000000;
9316 }
9317 return xx;
9318};
9319
9320//*
9321//* This is the mixing function that uses the sboxes
9322//*
9323Blowfish.prototype._F = function(xx) {
9324 let yy;
9325
9326 const dd = xx & 0x00FF;
9327 xx >>>= 8;
9328 const cc = xx & 0x00FF;
9329 xx >>>= 8;
9330 const bb = xx & 0x00FF;
9331 xx >>>= 8;
9332 const aa = xx & 0x00FF;
9333
9334 yy = this.sboxes[0][aa] + this.sboxes[1][bb];
9335 yy ^= this.sboxes[2][cc];
9336 yy += this.sboxes[3][dd];
9337
9338 return yy;
9339};
9340
9341//*
9342//* This method takes an array with two values, left and right
9343//* and does NN rounds of Blowfish on them.
9344//*
9345Blowfish.prototype._encrypt_block = function(vals) {
9346 let dataL = vals[0];
9347 let dataR = vals[1];
9348
9349 let ii;
9350
9351 for (ii = 0; ii < this.NN; ++ii) {
9352 dataL ^= this.parray[ii];
9353 dataR = this._F(dataL) ^ dataR;
9354
9355 const tmp = dataL;
9356 dataL = dataR;
9357 dataR = tmp;
9358 }
9359
9360 dataL ^= this.parray[this.NN + 0];
9361 dataR ^= this.parray[this.NN + 1];
9362
9363 vals[0] = this._clean(dataR);
9364 vals[1] = this._clean(dataL);
9365};
9366
9367//*
9368//* This method takes a vector of numbers and turns them
9369//* into long words so that they can be processed by the
9370//* real algorithm.
9371//*
9372//* Maybe I should make the real algorithm above take a vector
9373//* instead. That will involve more looping, but it won't require
9374//* the F() method to deconstruct the vector.
9375//*
9376Blowfish.prototype.encrypt_block = function(vector) {
9377 let ii;
9378 const vals = [0, 0];
9379 const off = this.BLOCKSIZE / 2;
9380 for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
9381 vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF);
9382 vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF);
9383 }
9384
9385 this._encrypt_block(vals);
9386
9387 const ret = [];
9388 for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
9389 ret[ii + 0] = ((vals[0] >>> (24 - 8 * (ii))) & 0x00FF);
9390 ret[ii + off] = ((vals[1] >>> (24 - 8 * (ii))) & 0x00FF);
9391 // vals[ 0 ] = ( vals[ 0 ] >>> 8 );
9392 // vals[ 1 ] = ( vals[ 1 ] >>> 8 );
9393 }
9394
9395 return ret;
9396};
9397
9398//*
9399//* This method takes an array with two values, left and right
9400//* and undoes NN rounds of Blowfish on them.
9401//*
9402Blowfish.prototype._decrypt_block = function(vals) {
9403 let dataL = vals[0];
9404 let dataR = vals[1];
9405
9406 let ii;
9407
9408 for (ii = this.NN + 1; ii > 1; --ii) {
9409 dataL ^= this.parray[ii];
9410 dataR = this._F(dataL) ^ dataR;
9411
9412 const tmp = dataL;
9413 dataL = dataR;
9414 dataR = tmp;
9415 }
9416
9417 dataL ^= this.parray[1];
9418 dataR ^= this.parray[0];
9419
9420 vals[0] = this._clean(dataR);
9421 vals[1] = this._clean(dataL);
9422};
9423
9424//*
9425//* This method takes a key array and initializes the
9426//* sboxes and parray for this encryption.
9427//*
9428Blowfish.prototype.init = function(key) {
9429 let ii;
9430 let jj = 0;
9431
9432 this.parray = [];
9433 for (ii = 0; ii < this.NN + 2; ++ii) {
9434 let data = 0x00000000;
9435 for (let kk = 0; kk < 4; ++kk) {
9436 data = (data << 8) | (key[jj] & 0x00FF);
9437 if (++jj >= key.length) {
9438 jj = 0;
9439 }
9440 }
9441 this.parray[ii] = this.PARRAY[ii] ^ data;
9442 }
9443
9444 this.sboxes = [];
9445 for (ii = 0; ii < 4; ++ii) {
9446 this.sboxes[ii] = [];
9447 for (jj = 0; jj < 256; ++jj) {
9448 this.sboxes[ii][jj] = this.SBOXES[ii][jj];
9449 }
9450 }
9451
9452 const vals = [0x00000000, 0x00000000];
9453
9454 for (ii = 0; ii < this.NN + 2; ii += 2) {
9455 this._encrypt_block(vals);
9456 this.parray[ii + 0] = vals[0];
9457 this.parray[ii + 1] = vals[1];
9458 }
9459
9460 for (ii = 0; ii < 4; ++ii) {
9461 for (jj = 0; jj < 256; jj += 2) {
9462 this._encrypt_block(vals);
9463 this.sboxes[ii][jj + 0] = vals[0];
9464 this.sboxes[ii][jj + 1] = vals[1];
9465 }
9466 }
9467};
9468
9469// added by Recurity Labs
9470function BF(key) {
9471 this.bf = new Blowfish();
9472 this.bf.init(key);
9473
9474 this.encrypt = function(block) {
9475 return this.bf.encrypt_block(block);
9476 };
9477}
9478
9479BF.keySize = BF.prototype.keySize = 16;
9480BF.blockSize = BF.prototype.blockSize = 8;
9481
9482/**
9483 * @fileoverview Symmetric cryptography functions
9484 * @module crypto/cipher
9485 * @private
9486 */
9487
9488/**
9489 * AES-128 encryption and decryption (ID 7)
9490 * @function
9491 * @param {String} key - 128-bit key
9492 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
9493 * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
9494 * @returns {Object}
9495 */
9496const aes128 = aes(128);
9497/**
9498 * AES-128 Block Cipher (ID 8)
9499 * @function
9500 * @param {String} key - 192-bit key
9501 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
9502 * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
9503 * @returns {Object}
9504 */
9505const aes192 = aes(192);
9506/**
9507 * AES-128 Block Cipher (ID 9)
9508 * @function
9509 * @param {String} key - 256-bit key
9510 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
9511 * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
9512 * @returns {Object}
9513 */
9514const aes256 = aes(256);
9515// Not in OpenPGP specifications
9516const des$1 = DES;
9517/**
9518 * Triple DES Block Cipher (ID 2)
9519 * @function
9520 * @param {String} key - 192-bit key
9521 * @see {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-67r2.pdf|NIST SP 800-67}
9522 * @returns {Object}
9523 */
9524const tripledes = TripleDES;
9525/**
9526 * CAST-128 Block Cipher (ID 3)
9527 * @function
9528 * @param {String} key - 128-bit key
9529 * @see {@link https://tools.ietf.org/html/rfc2144|The CAST-128 Encryption Algorithm}
9530 * @returns {Object}
9531 */
9532const cast5 = Cast5;
9533/**
9534 * Twofish Block Cipher (ID 10)
9535 * @function
9536 * @param {String} key - 256-bit key
9537 * @see {@link https://tools.ietf.org/html/rfc4880#ref-TWOFISH|TWOFISH}
9538 * @returns {Object}
9539 */
9540const twofish = TF;
9541/**
9542 * Blowfish Block Cipher (ID 4)
9543 * @function
9544 * @param {String} key - 128-bit key
9545 * @see {@link https://tools.ietf.org/html/rfc4880#ref-BLOWFISH|BLOWFISH}
9546 * @returns {Object}
9547 */
9548const blowfish = BF;
9549/**
9550 * Not implemented
9551 * @function
9552 * @throws {Error}
9553 */
9554const idea = function() {
9555 throw new Error('IDEA symmetric-key algorithm not implemented');
9556};
9557
9558var cipher = /*#__PURE__*/Object.freeze({
9559 __proto__: null,
9560 aes128: aes128,
9561 aes192: aes192,
9562 aes256: aes256,
9563 des: des$1,
9564 tripledes: tripledes,
9565 cast5: cast5,
9566 twofish: twofish,
9567 blowfish: blowfish,
9568 idea: idea
9569});
9570
9571var sha1_asm = function ( stdlib, foreign, buffer ) {
9572 "use asm";
9573
9574 // SHA256 state
9575 var H0 = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0,
9576 TOTAL0 = 0, TOTAL1 = 0;
9577
9578 // HMAC state
9579 var I0 = 0, I1 = 0, I2 = 0, I3 = 0, I4 = 0,
9580 O0 = 0, O1 = 0, O2 = 0, O3 = 0, O4 = 0;
9581
9582 // I/O buffer
9583 var HEAP = new stdlib.Uint8Array(buffer);
9584
9585 function _core ( w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15 ) {
9586 w0 = w0|0;
9587 w1 = w1|0;
9588 w2 = w2|0;
9589 w3 = w3|0;
9590 w4 = w4|0;
9591 w5 = w5|0;
9592 w6 = w6|0;
9593 w7 = w7|0;
9594 w8 = w8|0;
9595 w9 = w9|0;
9596 w10 = w10|0;
9597 w11 = w11|0;
9598 w12 = w12|0;
9599 w13 = w13|0;
9600 w14 = w14|0;
9601 w15 = w15|0;
9602
9603 var a = 0, b = 0, c = 0, d = 0, e = 0, n = 0, t = 0,
9604 w16 = 0, w17 = 0, w18 = 0, w19 = 0,
9605 w20 = 0, w21 = 0, w22 = 0, w23 = 0, w24 = 0, w25 = 0, w26 = 0, w27 = 0, w28 = 0, w29 = 0,
9606 w30 = 0, w31 = 0, w32 = 0, w33 = 0, w34 = 0, w35 = 0, w36 = 0, w37 = 0, w38 = 0, w39 = 0,
9607 w40 = 0, w41 = 0, w42 = 0, w43 = 0, w44 = 0, w45 = 0, w46 = 0, w47 = 0, w48 = 0, w49 = 0,
9608 w50 = 0, w51 = 0, w52 = 0, w53 = 0, w54 = 0, w55 = 0, w56 = 0, w57 = 0, w58 = 0, w59 = 0,
9609 w60 = 0, w61 = 0, w62 = 0, w63 = 0, w64 = 0, w65 = 0, w66 = 0, w67 = 0, w68 = 0, w69 = 0,
9610 w70 = 0, w71 = 0, w72 = 0, w73 = 0, w74 = 0, w75 = 0, w76 = 0, w77 = 0, w78 = 0, w79 = 0;
9611
9612 a = H0;
9613 b = H1;
9614 c = H2;
9615 d = H3;
9616 e = H4;
9617
9618 // 0
9619 t = ( w0 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9620 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9621
9622 // 1
9623 t = ( w1 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9624 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9625
9626 // 2
9627 t = ( w2 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9628 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9629
9630 // 3
9631 t = ( w3 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9632 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9633
9634 // 4
9635 t = ( w4 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9636 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9637
9638 // 5
9639 t = ( w5 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9640 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9641
9642 // 6
9643 t = ( w6 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9644 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9645
9646 // 7
9647 t = ( w7 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9648 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9649
9650 // 8
9651 t = ( w8 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9652 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9653
9654 // 9
9655 t = ( w9 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9656 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9657
9658 // 10
9659 t = ( w10 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9660 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9661
9662 // 11
9663 t = ( w11 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9664 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9665
9666 // 12
9667 t = ( w12 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9668 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9669
9670 // 13
9671 t = ( w13 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9672 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9673
9674 // 14
9675 t = ( w14 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9676 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9677
9678 // 15
9679 t = ( w15 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9680 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9681
9682 // 16
9683 n = w13 ^ w8 ^ w2 ^ w0;
9684 w16 = (n << 1) | (n >>> 31);
9685 t = (w16 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9686 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9687
9688 // 17
9689 n = w14 ^ w9 ^ w3 ^ w1;
9690 w17 = (n << 1) | (n >>> 31);
9691 t = (w17 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9692 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9693
9694 // 18
9695 n = w15 ^ w10 ^ w4 ^ w2;
9696 w18 = (n << 1) | (n >>> 31);
9697 t = (w18 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9698 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9699
9700 // 19
9701 n = w16 ^ w11 ^ w5 ^ w3;
9702 w19 = (n << 1) | (n >>> 31);
9703 t = (w19 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
9704 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9705
9706 // 20
9707 n = w17 ^ w12 ^ w6 ^ w4;
9708 w20 = (n << 1) | (n >>> 31);
9709 t = (w20 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9710 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9711
9712 // 21
9713 n = w18 ^ w13 ^ w7 ^ w5;
9714 w21 = (n << 1) | (n >>> 31);
9715 t = (w21 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9716 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9717
9718 // 22
9719 n = w19 ^ w14 ^ w8 ^ w6;
9720 w22 = (n << 1) | (n >>> 31);
9721 t = (w22 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9722 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9723
9724 // 23
9725 n = w20 ^ w15 ^ w9 ^ w7;
9726 w23 = (n << 1) | (n >>> 31);
9727 t = (w23 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9728 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9729
9730 // 24
9731 n = w21 ^ w16 ^ w10 ^ w8;
9732 w24 = (n << 1) | (n >>> 31);
9733 t = (w24 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9734 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9735
9736 // 25
9737 n = w22 ^ w17 ^ w11 ^ w9;
9738 w25 = (n << 1) | (n >>> 31);
9739 t = (w25 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9740 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9741
9742 // 26
9743 n = w23 ^ w18 ^ w12 ^ w10;
9744 w26 = (n << 1) | (n >>> 31);
9745 t = (w26 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9746 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9747
9748 // 27
9749 n = w24 ^ w19 ^ w13 ^ w11;
9750 w27 = (n << 1) | (n >>> 31);
9751 t = (w27 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9752 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9753
9754 // 28
9755 n = w25 ^ w20 ^ w14 ^ w12;
9756 w28 = (n << 1) | (n >>> 31);
9757 t = (w28 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9758 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9759
9760 // 29
9761 n = w26 ^ w21 ^ w15 ^ w13;
9762 w29 = (n << 1) | (n >>> 31);
9763 t = (w29 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9764 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9765
9766 // 30
9767 n = w27 ^ w22 ^ w16 ^ w14;
9768 w30 = (n << 1) | (n >>> 31);
9769 t = (w30 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9770 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9771
9772 // 31
9773 n = w28 ^ w23 ^ w17 ^ w15;
9774 w31 = (n << 1) | (n >>> 31);
9775 t = (w31 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9776 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9777
9778 // 32
9779 n = w29 ^ w24 ^ w18 ^ w16;
9780 w32 = (n << 1) | (n >>> 31);
9781 t = (w32 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9782 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9783
9784 // 33
9785 n = w30 ^ w25 ^ w19 ^ w17;
9786 w33 = (n << 1) | (n >>> 31);
9787 t = (w33 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9788 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9789
9790 // 34
9791 n = w31 ^ w26 ^ w20 ^ w18;
9792 w34 = (n << 1) | (n >>> 31);
9793 t = (w34 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9794 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9795
9796 // 35
9797 n = w32 ^ w27 ^ w21 ^ w19;
9798 w35 = (n << 1) | (n >>> 31);
9799 t = (w35 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9800 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9801
9802 // 36
9803 n = w33 ^ w28 ^ w22 ^ w20;
9804 w36 = (n << 1) | (n >>> 31);
9805 t = (w36 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9806 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9807
9808 // 37
9809 n = w34 ^ w29 ^ w23 ^ w21;
9810 w37 = (n << 1) | (n >>> 31);
9811 t = (w37 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9812 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9813
9814 // 38
9815 n = w35 ^ w30 ^ w24 ^ w22;
9816 w38 = (n << 1) | (n >>> 31);
9817 t = (w38 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9818 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9819
9820 // 39
9821 n = w36 ^ w31 ^ w25 ^ w23;
9822 w39 = (n << 1) | (n >>> 31);
9823 t = (w39 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
9824 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9825
9826 // 40
9827 n = w37 ^ w32 ^ w26 ^ w24;
9828 w40 = (n << 1) | (n >>> 31);
9829 t = (w40 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9830 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9831
9832 // 41
9833 n = w38 ^ w33 ^ w27 ^ w25;
9834 w41 = (n << 1) | (n >>> 31);
9835 t = (w41 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9836 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9837
9838 // 42
9839 n = w39 ^ w34 ^ w28 ^ w26;
9840 w42 = (n << 1) | (n >>> 31);
9841 t = (w42 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9842 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9843
9844 // 43
9845 n = w40 ^ w35 ^ w29 ^ w27;
9846 w43 = (n << 1) | (n >>> 31);
9847 t = (w43 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9848 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9849
9850 // 44
9851 n = w41 ^ w36 ^ w30 ^ w28;
9852 w44 = (n << 1) | (n >>> 31);
9853 t = (w44 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9854 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9855
9856 // 45
9857 n = w42 ^ w37 ^ w31 ^ w29;
9858 w45 = (n << 1) | (n >>> 31);
9859 t = (w45 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9860 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9861
9862 // 46
9863 n = w43 ^ w38 ^ w32 ^ w30;
9864 w46 = (n << 1) | (n >>> 31);
9865 t = (w46 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9866 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9867
9868 // 47
9869 n = w44 ^ w39 ^ w33 ^ w31;
9870 w47 = (n << 1) | (n >>> 31);
9871 t = (w47 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9872 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9873
9874 // 48
9875 n = w45 ^ w40 ^ w34 ^ w32;
9876 w48 = (n << 1) | (n >>> 31);
9877 t = (w48 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9878 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9879
9880 // 49
9881 n = w46 ^ w41 ^ w35 ^ w33;
9882 w49 = (n << 1) | (n >>> 31);
9883 t = (w49 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9884 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9885
9886 // 50
9887 n = w47 ^ w42 ^ w36 ^ w34;
9888 w50 = (n << 1) | (n >>> 31);
9889 t = (w50 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9890 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9891
9892 // 51
9893 n = w48 ^ w43 ^ w37 ^ w35;
9894 w51 = (n << 1) | (n >>> 31);
9895 t = (w51 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9896 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9897
9898 // 52
9899 n = w49 ^ w44 ^ w38 ^ w36;
9900 w52 = (n << 1) | (n >>> 31);
9901 t = (w52 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9902 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9903
9904 // 53
9905 n = w50 ^ w45 ^ w39 ^ w37;
9906 w53 = (n << 1) | (n >>> 31);
9907 t = (w53 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9908 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9909
9910 // 54
9911 n = w51 ^ w46 ^ w40 ^ w38;
9912 w54 = (n << 1) | (n >>> 31);
9913 t = (w54 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9914 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9915
9916 // 55
9917 n = w52 ^ w47 ^ w41 ^ w39;
9918 w55 = (n << 1) | (n >>> 31);
9919 t = (w55 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9920 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9921
9922 // 56
9923 n = w53 ^ w48 ^ w42 ^ w40;
9924 w56 = (n << 1) | (n >>> 31);
9925 t = (w56 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9926 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9927
9928 // 57
9929 n = w54 ^ w49 ^ w43 ^ w41;
9930 w57 = (n << 1) | (n >>> 31);
9931 t = (w57 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9932 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9933
9934 // 58
9935 n = w55 ^ w50 ^ w44 ^ w42;
9936 w58 = (n << 1) | (n >>> 31);
9937 t = (w58 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9938 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9939
9940 // 59
9941 n = w56 ^ w51 ^ w45 ^ w43;
9942 w59 = (n << 1) | (n >>> 31);
9943 t = (w59 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
9944 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9945
9946 // 60
9947 n = w57 ^ w52 ^ w46 ^ w44;
9948 w60 = (n << 1) | (n >>> 31);
9949 t = (w60 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9950 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9951
9952 // 61
9953 n = w58 ^ w53 ^ w47 ^ w45;
9954 w61 = (n << 1) | (n >>> 31);
9955 t = (w61 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9956 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9957
9958 // 62
9959 n = w59 ^ w54 ^ w48 ^ w46;
9960 w62 = (n << 1) | (n >>> 31);
9961 t = (w62 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9962 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9963
9964 // 63
9965 n = w60 ^ w55 ^ w49 ^ w47;
9966 w63 = (n << 1) | (n >>> 31);
9967 t = (w63 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9968 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9969
9970 // 64
9971 n = w61 ^ w56 ^ w50 ^ w48;
9972 w64 = (n << 1) | (n >>> 31);
9973 t = (w64 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9974 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9975
9976 // 65
9977 n = w62 ^ w57 ^ w51 ^ w49;
9978 w65 = (n << 1) | (n >>> 31);
9979 t = (w65 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9980 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9981
9982 // 66
9983 n = w63 ^ w58 ^ w52 ^ w50;
9984 w66 = (n << 1) | (n >>> 31);
9985 t = (w66 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9986 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9987
9988 // 67
9989 n = w64 ^ w59 ^ w53 ^ w51;
9990 w67 = (n << 1) | (n >>> 31);
9991 t = (w67 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9992 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9993
9994 // 68
9995 n = w65 ^ w60 ^ w54 ^ w52;
9996 w68 = (n << 1) | (n >>> 31);
9997 t = (w68 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
9998 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
9999
10000 // 69
10001 n = w66 ^ w61 ^ w55 ^ w53;
10002 w69 = (n << 1) | (n >>> 31);
10003 t = (w69 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10004 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10005
10006 // 70
10007 n = w67 ^ w62 ^ w56 ^ w54;
10008 w70 = (n << 1) | (n >>> 31);
10009 t = (w70 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10010 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10011
10012 // 71
10013 n = w68 ^ w63 ^ w57 ^ w55;
10014 w71 = (n << 1) | (n >>> 31);
10015 t = (w71 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10016 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10017
10018 // 72
10019 n = w69 ^ w64 ^ w58 ^ w56;
10020 w72 = (n << 1) | (n >>> 31);
10021 t = (w72 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10022 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10023
10024 // 73
10025 n = w70 ^ w65 ^ w59 ^ w57;
10026 w73 = (n << 1) | (n >>> 31);
10027 t = (w73 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10028 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10029
10030 // 74
10031 n = w71 ^ w66 ^ w60 ^ w58;
10032 w74 = (n << 1) | (n >>> 31);
10033 t = (w74 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10034 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10035
10036 // 75
10037 n = w72 ^ w67 ^ w61 ^ w59;
10038 w75 = (n << 1) | (n >>> 31);
10039 t = (w75 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10040 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10041
10042 // 76
10043 n = w73 ^ w68 ^ w62 ^ w60;
10044 w76 = (n << 1) | (n >>> 31);
10045 t = (w76 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10046 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10047
10048 // 77
10049 n = w74 ^ w69 ^ w63 ^ w61;
10050 w77 = (n << 1) | (n >>> 31);
10051 t = (w77 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10052 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10053
10054 // 78
10055 n = w75 ^ w70 ^ w64 ^ w62;
10056 w78 = (n << 1) | (n >>> 31);
10057 t = (w78 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10058 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10059
10060 // 79
10061 n = w76 ^ w71 ^ w65 ^ w63;
10062 w79 = (n << 1) | (n >>> 31);
10063 t = (w79 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
10064 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
10065
10066 H0 = ( H0 + a )|0;
10067 H1 = ( H1 + b )|0;
10068 H2 = ( H2 + c )|0;
10069 H3 = ( H3 + d )|0;
10070 H4 = ( H4 + e )|0;
10071
10072 }
10073
10074 function _core_heap ( offset ) {
10075 offset = offset|0;
10076
10077 _core(
10078 HEAP[offset|0]<<24 | HEAP[offset|1]<<16 | HEAP[offset|2]<<8 | HEAP[offset|3],
10079 HEAP[offset|4]<<24 | HEAP[offset|5]<<16 | HEAP[offset|6]<<8 | HEAP[offset|7],
10080 HEAP[offset|8]<<24 | HEAP[offset|9]<<16 | HEAP[offset|10]<<8 | HEAP[offset|11],
10081 HEAP[offset|12]<<24 | HEAP[offset|13]<<16 | HEAP[offset|14]<<8 | HEAP[offset|15],
10082 HEAP[offset|16]<<24 | HEAP[offset|17]<<16 | HEAP[offset|18]<<8 | HEAP[offset|19],
10083 HEAP[offset|20]<<24 | HEAP[offset|21]<<16 | HEAP[offset|22]<<8 | HEAP[offset|23],
10084 HEAP[offset|24]<<24 | HEAP[offset|25]<<16 | HEAP[offset|26]<<8 | HEAP[offset|27],
10085 HEAP[offset|28]<<24 | HEAP[offset|29]<<16 | HEAP[offset|30]<<8 | HEAP[offset|31],
10086 HEAP[offset|32]<<24 | HEAP[offset|33]<<16 | HEAP[offset|34]<<8 | HEAP[offset|35],
10087 HEAP[offset|36]<<24 | HEAP[offset|37]<<16 | HEAP[offset|38]<<8 | HEAP[offset|39],
10088 HEAP[offset|40]<<24 | HEAP[offset|41]<<16 | HEAP[offset|42]<<8 | HEAP[offset|43],
10089 HEAP[offset|44]<<24 | HEAP[offset|45]<<16 | HEAP[offset|46]<<8 | HEAP[offset|47],
10090 HEAP[offset|48]<<24 | HEAP[offset|49]<<16 | HEAP[offset|50]<<8 | HEAP[offset|51],
10091 HEAP[offset|52]<<24 | HEAP[offset|53]<<16 | HEAP[offset|54]<<8 | HEAP[offset|55],
10092 HEAP[offset|56]<<24 | HEAP[offset|57]<<16 | HEAP[offset|58]<<8 | HEAP[offset|59],
10093 HEAP[offset|60]<<24 | HEAP[offset|61]<<16 | HEAP[offset|62]<<8 | HEAP[offset|63]
10094 );
10095 }
10096
10097 // offset — multiple of 32
10098 function _state_to_heap ( output ) {
10099 output = output|0;
10100
10101 HEAP[output|0] = H0>>>24;
10102 HEAP[output|1] = H0>>>16&255;
10103 HEAP[output|2] = H0>>>8&255;
10104 HEAP[output|3] = H0&255;
10105 HEAP[output|4] = H1>>>24;
10106 HEAP[output|5] = H1>>>16&255;
10107 HEAP[output|6] = H1>>>8&255;
10108 HEAP[output|7] = H1&255;
10109 HEAP[output|8] = H2>>>24;
10110 HEAP[output|9] = H2>>>16&255;
10111 HEAP[output|10] = H2>>>8&255;
10112 HEAP[output|11] = H2&255;
10113 HEAP[output|12] = H3>>>24;
10114 HEAP[output|13] = H3>>>16&255;
10115 HEAP[output|14] = H3>>>8&255;
10116 HEAP[output|15] = H3&255;
10117 HEAP[output|16] = H4>>>24;
10118 HEAP[output|17] = H4>>>16&255;
10119 HEAP[output|18] = H4>>>8&255;
10120 HEAP[output|19] = H4&255;
10121 }
10122
10123 function reset () {
10124 H0 = 0x67452301;
10125 H1 = 0xefcdab89;
10126 H2 = 0x98badcfe;
10127 H3 = 0x10325476;
10128 H4 = 0xc3d2e1f0;
10129 TOTAL0 = TOTAL1 = 0;
10130 }
10131
10132 function init ( h0, h1, h2, h3, h4, total0, total1 ) {
10133 h0 = h0|0;
10134 h1 = h1|0;
10135 h2 = h2|0;
10136 h3 = h3|0;
10137 h4 = h4|0;
10138 total0 = total0|0;
10139 total1 = total1|0;
10140
10141 H0 = h0;
10142 H1 = h1;
10143 H2 = h2;
10144 H3 = h3;
10145 H4 = h4;
10146 TOTAL0 = total0;
10147 TOTAL1 = total1;
10148 }
10149
10150 // offset — multiple of 64
10151 function process ( offset, length ) {
10152 offset = offset|0;
10153 length = length|0;
10154
10155 var hashed = 0;
10156
10157 if ( offset & 63 )
10158 return -1;
10159
10160 while ( (length|0) >= 64 ) {
10161 _core_heap(offset);
10162
10163 offset = ( offset + 64 )|0;
10164 length = ( length - 64 )|0;
10165
10166 hashed = ( hashed + 64 )|0;
10167 }
10168
10169 TOTAL0 = ( TOTAL0 + hashed )|0;
10170 if ( TOTAL0>>>0 < hashed>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0;
10171
10172 return hashed|0;
10173 }
10174
10175 // offset — multiple of 64
10176 // output — multiple of 32
10177 function finish ( offset, length, output ) {
10178 offset = offset|0;
10179 length = length|0;
10180 output = output|0;
10181
10182 var hashed = 0,
10183 i = 0;
10184
10185 if ( offset & 63 )
10186 return -1;
10187
10188 if ( ~output )
10189 if ( output & 31 )
10190 return -1;
10191
10192 if ( (length|0) >= 64 ) {
10193 hashed = process( offset, length )|0;
10194 if ( (hashed|0) == -1 )
10195 return -1;
10196
10197 offset = ( offset + hashed )|0;
10198 length = ( length - hashed )|0;
10199 }
10200
10201 hashed = ( hashed + length )|0;
10202 TOTAL0 = ( TOTAL0 + length )|0;
10203 if ( TOTAL0>>>0 < length>>>0 ) TOTAL1 = (TOTAL1 + 1)|0;
10204
10205 HEAP[offset|length] = 0x80;
10206
10207 if ( (length|0) >= 56 ) {
10208 for ( i = (length+1)|0; (i|0) < 64; i = (i+1)|0 )
10209 HEAP[offset|i] = 0x00;
10210 _core_heap(offset);
10211
10212 length = 0;
10213
10214 HEAP[offset|0] = 0;
10215 }
10216
10217 for ( i = (length+1)|0; (i|0) < 59; i = (i+1)|0 )
10218 HEAP[offset|i] = 0;
10219
10220 HEAP[offset|56] = TOTAL1>>>21&255;
10221 HEAP[offset|57] = TOTAL1>>>13&255;
10222 HEAP[offset|58] = TOTAL1>>>5&255;
10223 HEAP[offset|59] = TOTAL1<<3&255 | TOTAL0>>>29;
10224 HEAP[offset|60] = TOTAL0>>>21&255;
10225 HEAP[offset|61] = TOTAL0>>>13&255;
10226 HEAP[offset|62] = TOTAL0>>>5&255;
10227 HEAP[offset|63] = TOTAL0<<3&255;
10228 _core_heap(offset);
10229
10230 if ( ~output )
10231 _state_to_heap(output);
10232
10233 return hashed|0;
10234 }
10235
10236 function hmac_reset () {
10237 H0 = I0;
10238 H1 = I1;
10239 H2 = I2;
10240 H3 = I3;
10241 H4 = I4;
10242 TOTAL0 = 64;
10243 TOTAL1 = 0;
10244 }
10245
10246 function _hmac_opad () {
10247 H0 = O0;
10248 H1 = O1;
10249 H2 = O2;
10250 H3 = O3;
10251 H4 = O4;
10252 TOTAL0 = 64;
10253 TOTAL1 = 0;
10254 }
10255
10256 function hmac_init ( p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 ) {
10257 p0 = p0|0;
10258 p1 = p1|0;
10259 p2 = p2|0;
10260 p3 = p3|0;
10261 p4 = p4|0;
10262 p5 = p5|0;
10263 p6 = p6|0;
10264 p7 = p7|0;
10265 p8 = p8|0;
10266 p9 = p9|0;
10267 p10 = p10|0;
10268 p11 = p11|0;
10269 p12 = p12|0;
10270 p13 = p13|0;
10271 p14 = p14|0;
10272 p15 = p15|0;
10273
10274 // opad
10275 reset();
10276 _core(
10277 p0 ^ 0x5c5c5c5c,
10278 p1 ^ 0x5c5c5c5c,
10279 p2 ^ 0x5c5c5c5c,
10280 p3 ^ 0x5c5c5c5c,
10281 p4 ^ 0x5c5c5c5c,
10282 p5 ^ 0x5c5c5c5c,
10283 p6 ^ 0x5c5c5c5c,
10284 p7 ^ 0x5c5c5c5c,
10285 p8 ^ 0x5c5c5c5c,
10286 p9 ^ 0x5c5c5c5c,
10287 p10 ^ 0x5c5c5c5c,
10288 p11 ^ 0x5c5c5c5c,
10289 p12 ^ 0x5c5c5c5c,
10290 p13 ^ 0x5c5c5c5c,
10291 p14 ^ 0x5c5c5c5c,
10292 p15 ^ 0x5c5c5c5c
10293 );
10294 O0 = H0;
10295 O1 = H1;
10296 O2 = H2;
10297 O3 = H3;
10298 O4 = H4;
10299
10300 // ipad
10301 reset();
10302 _core(
10303 p0 ^ 0x36363636,
10304 p1 ^ 0x36363636,
10305 p2 ^ 0x36363636,
10306 p3 ^ 0x36363636,
10307 p4 ^ 0x36363636,
10308 p5 ^ 0x36363636,
10309 p6 ^ 0x36363636,
10310 p7 ^ 0x36363636,
10311 p8 ^ 0x36363636,
10312 p9 ^ 0x36363636,
10313 p10 ^ 0x36363636,
10314 p11 ^ 0x36363636,
10315 p12 ^ 0x36363636,
10316 p13 ^ 0x36363636,
10317 p14 ^ 0x36363636,
10318 p15 ^ 0x36363636
10319 );
10320 I0 = H0;
10321 I1 = H1;
10322 I2 = H2;
10323 I3 = H3;
10324 I4 = H4;
10325
10326 TOTAL0 = 64;
10327 TOTAL1 = 0;
10328 }
10329
10330 // offset — multiple of 64
10331 // output — multiple of 32
10332 function hmac_finish ( offset, length, output ) {
10333 offset = offset|0;
10334 length = length|0;
10335 output = output|0;
10336
10337 var t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, hashed = 0;
10338
10339 if ( offset & 63 )
10340 return -1;
10341
10342 if ( ~output )
10343 if ( output & 31 )
10344 return -1;
10345
10346 hashed = finish( offset, length, -1 )|0;
10347 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4;
10348
10349 _hmac_opad();
10350 _core( t0, t1, t2, t3, t4, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672 );
10351
10352 if ( ~output )
10353 _state_to_heap(output);
10354
10355 return hashed|0;
10356 }
10357
10358 // salt is assumed to be already processed
10359 // offset — multiple of 64
10360 // output — multiple of 32
10361 function pbkdf2_generate_block ( offset, length, block, count, output ) {
10362 offset = offset|0;
10363 length = length|0;
10364 block = block|0;
10365 count = count|0;
10366 output = output|0;
10367
10368 var h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0,
10369 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;
10370
10371 if ( offset & 63 )
10372 return -1;
10373
10374 if ( ~output )
10375 if ( output & 31 )
10376 return -1;
10377
10378 // pad block number into heap
10379 // FIXME probable OOB write
10380 HEAP[(offset+length)|0] = block>>>24;
10381 HEAP[(offset+length+1)|0] = block>>>16&255;
10382 HEAP[(offset+length+2)|0] = block>>>8&255;
10383 HEAP[(offset+length+3)|0] = block&255;
10384
10385 // finish first iteration
10386 hmac_finish( offset, (length+4)|0, -1 )|0;
10387 h0 = t0 = H0, h1 = t1 = H1, h2 = t2 = H2, h3 = t3 = H3, h4 = t4 = H4;
10388 count = (count-1)|0;
10389
10390 // perform the rest iterations
10391 while ( (count|0) > 0 ) {
10392 hmac_reset();
10393 _core( t0, t1, t2, t3, t4, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672 );
10394 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4;
10395
10396 _hmac_opad();
10397 _core( t0, t1, t2, t3, t4, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672 );
10398 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4;
10399
10400 h0 = h0 ^ H0;
10401 h1 = h1 ^ H1;
10402 h2 = h2 ^ H2;
10403 h3 = h3 ^ H3;
10404 h4 = h4 ^ H4;
10405
10406 count = (count-1)|0;
10407 }
10408
10409 H0 = h0;
10410 H1 = h1;
10411 H2 = h2;
10412 H3 = h3;
10413 H4 = h4;
10414
10415 if ( ~output )
10416 _state_to_heap(output);
10417
10418 return 0;
10419 }
10420
10421 return {
10422 // SHA1
10423 reset: reset,
10424 init: init,
10425 process: process,
10426 finish: finish,
10427
10428 // HMAC-SHA1
10429 hmac_reset: hmac_reset,
10430 hmac_init: hmac_init,
10431 hmac_finish: hmac_finish,
10432
10433 // PBKDF2-HMAC-SHA1
10434 pbkdf2_generate_block: pbkdf2_generate_block
10435 }
10436};
10437
10438class Hash {
10439 constructor() {
10440 this.pos = 0;
10441 this.len = 0;
10442 }
10443 reset() {
10444 const { asm } = this.acquire_asm();
10445 this.result = null;
10446 this.pos = 0;
10447 this.len = 0;
10448 asm.reset();
10449 return this;
10450 }
10451 process(data) {
10452 if (this.result !== null)
10453 throw new IllegalStateError('state must be reset before processing new data');
10454 const { asm, heap } = this.acquire_asm();
10455 let hpos = this.pos;
10456 let hlen = this.len;
10457 let dpos = 0;
10458 let dlen = data.length;
10459 let wlen = 0;
10460 while (dlen > 0) {
10461 wlen = _heap_write(heap, hpos + hlen, data, dpos, dlen);
10462 hlen += wlen;
10463 dpos += wlen;
10464 dlen -= wlen;
10465 wlen = asm.process(hpos, hlen);
10466 hpos += wlen;
10467 hlen -= wlen;
10468 if (!hlen)
10469 hpos = 0;
10470 }
10471 this.pos = hpos;
10472 this.len = hlen;
10473 return this;
10474 }
10475 finish() {
10476 if (this.result !== null)
10477 throw new IllegalStateError('state must be reset before processing new data');
10478 const { asm, heap } = this.acquire_asm();
10479 asm.finish(this.pos, this.len, 0);
10480 this.result = new Uint8Array(this.HASH_SIZE);
10481 this.result.set(heap.subarray(0, this.HASH_SIZE));
10482 this.pos = 0;
10483 this.len = 0;
10484 this.release_asm();
10485 return this;
10486 }
10487}
10488
10489const _sha1_block_size = 64;
10490const _sha1_hash_size = 20;
10491const heap_pool$1 = [];
10492const asm_pool$1 = [];
10493class Sha1 extends Hash {
10494 constructor() {
10495 super();
10496 this.NAME = 'sha1';
10497 this.BLOCK_SIZE = _sha1_block_size;
10498 this.HASH_SIZE = _sha1_hash_size;
10499 this.acquire_asm();
10500 }
10501 acquire_asm() {
10502 if (this.heap === undefined || this.asm === undefined) {
10503 this.heap = heap_pool$1.pop() || _heap_init();
10504 this.asm = asm_pool$1.pop() || sha1_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
10505 this.reset();
10506 }
10507 return { heap: this.heap, asm: this.asm };
10508 }
10509 release_asm() {
10510 if (this.heap !== undefined && this.asm !== undefined) {
10511 heap_pool$1.push(this.heap);
10512 asm_pool$1.push(this.asm);
10513 }
10514 this.heap = undefined;
10515 this.asm = undefined;
10516 }
10517 static bytes(data) {
10518 return new Sha1().process(data).finish().result;
10519 }
10520}
10521Sha1.NAME = 'sha1';
10522Sha1.heap_pool = [];
10523Sha1.asm_pool = [];
10524Sha1.asm_function = sha1_asm;
10525
10526var sha256_asm = function ( stdlib, foreign, buffer ) {
10527 "use asm";
10528
10529 // SHA256 state
10530 var H0 = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0, H5 = 0, H6 = 0, H7 = 0,
10531 TOTAL0 = 0, TOTAL1 = 0;
10532
10533 // HMAC state
10534 var I0 = 0, I1 = 0, I2 = 0, I3 = 0, I4 = 0, I5 = 0, I6 = 0, I7 = 0,
10535 O0 = 0, O1 = 0, O2 = 0, O3 = 0, O4 = 0, O5 = 0, O6 = 0, O7 = 0;
10536
10537 // I/O buffer
10538 var HEAP = new stdlib.Uint8Array(buffer);
10539
10540 function _core ( w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15 ) {
10541 w0 = w0|0;
10542 w1 = w1|0;
10543 w2 = w2|0;
10544 w3 = w3|0;
10545 w4 = w4|0;
10546 w5 = w5|0;
10547 w6 = w6|0;
10548 w7 = w7|0;
10549 w8 = w8|0;
10550 w9 = w9|0;
10551 w10 = w10|0;
10552 w11 = w11|0;
10553 w12 = w12|0;
10554 w13 = w13|0;
10555 w14 = w14|0;
10556 w15 = w15|0;
10557
10558 var a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
10559
10560 a = H0;
10561 b = H1;
10562 c = H2;
10563 d = H3;
10564 e = H4;
10565 f = H5;
10566 g = H6;
10567 h = H7;
10568
10569 // 0
10570 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x428a2f98 )|0;
10571 d = ( d + h )|0;
10572 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10573
10574 // 1
10575 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x71374491 )|0;
10576 c = ( c + g )|0;
10577 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10578
10579 // 2
10580 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0xb5c0fbcf )|0;
10581 b = ( b + f )|0;
10582 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10583
10584 // 3
10585 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0xe9b5dba5 )|0;
10586 a = ( a + e )|0;
10587 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10588
10589 // 4
10590 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x3956c25b )|0;
10591 h = ( h + d )|0;
10592 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10593
10594 // 5
10595 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x59f111f1 )|0;
10596 g = ( g + c )|0;
10597 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10598
10599 // 6
10600 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x923f82a4 )|0;
10601 f = ( f + b )|0;
10602 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10603
10604 // 7
10605 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0xab1c5ed5 )|0;
10606 e = ( e + a )|0;
10607 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10608
10609 // 8
10610 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xd807aa98 )|0;
10611 d = ( d + h )|0;
10612 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10613
10614 // 9
10615 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x12835b01 )|0;
10616 c = ( c + g )|0;
10617 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10618
10619 // 10
10620 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x243185be )|0;
10621 b = ( b + f )|0;
10622 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10623
10624 // 11
10625 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x550c7dc3 )|0;
10626 a = ( a + e )|0;
10627 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10628
10629 // 12
10630 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x72be5d74 )|0;
10631 h = ( h + d )|0;
10632 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10633
10634 // 13
10635 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x80deb1fe )|0;
10636 g = ( g + c )|0;
10637 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10638
10639 // 14
10640 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x9bdc06a7 )|0;
10641 f = ( f + b )|0;
10642 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10643
10644 // 15
10645 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0xc19bf174 )|0;
10646 e = ( e + a )|0;
10647 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10648
10649 // 16
10650 w0 = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0;
10651 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xe49b69c1 )|0;
10652 d = ( d + h )|0;
10653 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10654
10655 // 17
10656 w1 = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0;
10657 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0xefbe4786 )|0;
10658 c = ( c + g )|0;
10659 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10660
10661 // 18
10662 w2 = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0;
10663 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x0fc19dc6 )|0;
10664 b = ( b + f )|0;
10665 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10666
10667 // 19
10668 w3 = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0;
10669 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x240ca1cc )|0;
10670 a = ( a + e )|0;
10671 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10672
10673 // 20
10674 w4 = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0;
10675 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x2de92c6f )|0;
10676 h = ( h + d )|0;
10677 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10678
10679 // 21
10680 w5 = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0;
10681 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x4a7484aa )|0;
10682 g = ( g + c )|0;
10683 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10684
10685 // 22
10686 w6 = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0;
10687 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x5cb0a9dc )|0;
10688 f = ( f + b )|0;
10689 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10690
10691 // 23
10692 w7 = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0;
10693 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x76f988da )|0;
10694 e = ( e + a )|0;
10695 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10696
10697 // 24
10698 w8 = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0;
10699 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x983e5152 )|0;
10700 d = ( d + h )|0;
10701 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10702
10703 // 25
10704 w9 = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0;
10705 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0xa831c66d )|0;
10706 c = ( c + g )|0;
10707 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10708
10709 // 26
10710 w10 = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0;
10711 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0xb00327c8 )|0;
10712 b = ( b + f )|0;
10713 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10714
10715 // 27
10716 w11 = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0;
10717 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0xbf597fc7 )|0;
10718 a = ( a + e )|0;
10719 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10720
10721 // 28
10722 w12 = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0;
10723 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0xc6e00bf3 )|0;
10724 h = ( h + d )|0;
10725 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10726
10727 // 29
10728 w13 = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0;
10729 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0xd5a79147 )|0;
10730 g = ( g + c )|0;
10731 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10732
10733 // 30
10734 w14 = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0;
10735 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x06ca6351 )|0;
10736 f = ( f + b )|0;
10737 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10738
10739 // 31
10740 w15 = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0;
10741 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x14292967 )|0;
10742 e = ( e + a )|0;
10743 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10744
10745 // 32
10746 w0 = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0;
10747 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x27b70a85 )|0;
10748 d = ( d + h )|0;
10749 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10750
10751 // 33
10752 w1 = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0;
10753 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x2e1b2138 )|0;
10754 c = ( c + g )|0;
10755 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10756
10757 // 34
10758 w2 = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0;
10759 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x4d2c6dfc )|0;
10760 b = ( b + f )|0;
10761 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10762
10763 // 35
10764 w3 = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0;
10765 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x53380d13 )|0;
10766 a = ( a + e )|0;
10767 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10768
10769 // 36
10770 w4 = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0;
10771 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x650a7354 )|0;
10772 h = ( h + d )|0;
10773 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10774
10775 // 37
10776 w5 = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0;
10777 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x766a0abb )|0;
10778 g = ( g + c )|0;
10779 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10780
10781 // 38
10782 w6 = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0;
10783 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x81c2c92e )|0;
10784 f = ( f + b )|0;
10785 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10786
10787 // 39
10788 w7 = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0;
10789 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x92722c85 )|0;
10790 e = ( e + a )|0;
10791 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10792
10793 // 40
10794 w8 = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0;
10795 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xa2bfe8a1 )|0;
10796 d = ( d + h )|0;
10797 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10798
10799 // 41
10800 w9 = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0;
10801 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0xa81a664b )|0;
10802 c = ( c + g )|0;
10803 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10804
10805 // 42
10806 w10 = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0;
10807 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0xc24b8b70 )|0;
10808 b = ( b + f )|0;
10809 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10810
10811 // 43
10812 w11 = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0;
10813 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0xc76c51a3 )|0;
10814 a = ( a + e )|0;
10815 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10816
10817 // 44
10818 w12 = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0;
10819 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0xd192e819 )|0;
10820 h = ( h + d )|0;
10821 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10822
10823 // 45
10824 w13 = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0;
10825 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0xd6990624 )|0;
10826 g = ( g + c )|0;
10827 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10828
10829 // 46
10830 w14 = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0;
10831 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0xf40e3585 )|0;
10832 f = ( f + b )|0;
10833 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10834
10835 // 47
10836 w15 = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0;
10837 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x106aa070 )|0;
10838 e = ( e + a )|0;
10839 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10840
10841 // 48
10842 w0 = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0;
10843 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x19a4c116 )|0;
10844 d = ( d + h )|0;
10845 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10846
10847 // 49
10848 w1 = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0;
10849 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x1e376c08 )|0;
10850 c = ( c + g )|0;
10851 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10852
10853 // 50
10854 w2 = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0;
10855 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x2748774c )|0;
10856 b = ( b + f )|0;
10857 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10858
10859 // 51
10860 w3 = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0;
10861 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x34b0bcb5 )|0;
10862 a = ( a + e )|0;
10863 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10864
10865 // 52
10866 w4 = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0;
10867 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x391c0cb3 )|0;
10868 h = ( h + d )|0;
10869 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10870
10871 // 53
10872 w5 = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0;
10873 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x4ed8aa4a )|0;
10874 g = ( g + c )|0;
10875 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10876
10877 // 54
10878 w6 = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0;
10879 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x5b9cca4f )|0;
10880 f = ( f + b )|0;
10881 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10882
10883 // 55
10884 w7 = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0;
10885 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x682e6ff3 )|0;
10886 e = ( e + a )|0;
10887 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10888
10889 // 56
10890 w8 = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0;
10891 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x748f82ee )|0;
10892 d = ( d + h )|0;
10893 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
10894
10895 // 57
10896 w9 = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0;
10897 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x78a5636f )|0;
10898 c = ( c + g )|0;
10899 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
10900
10901 // 58
10902 w10 = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0;
10903 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x84c87814 )|0;
10904 b = ( b + f )|0;
10905 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
10906
10907 // 59
10908 w11 = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0;
10909 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x8cc70208 )|0;
10910 a = ( a + e )|0;
10911 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
10912
10913 // 60
10914 w12 = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0;
10915 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x90befffa )|0;
10916 h = ( h + d )|0;
10917 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
10918
10919 // 61
10920 w13 = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0;
10921 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0xa4506ceb )|0;
10922 g = ( g + c )|0;
10923 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
10924
10925 // 62
10926 w14 = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0;
10927 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0xbef9a3f7 )|0;
10928 f = ( f + b )|0;
10929 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
10930
10931 // 63
10932 w15 = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0;
10933 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0xc67178f2 )|0;
10934 e = ( e + a )|0;
10935 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
10936
10937 H0 = ( H0 + a )|0;
10938 H1 = ( H1 + b )|0;
10939 H2 = ( H2 + c )|0;
10940 H3 = ( H3 + d )|0;
10941 H4 = ( H4 + e )|0;
10942 H5 = ( H5 + f )|0;
10943 H6 = ( H6 + g )|0;
10944 H7 = ( H7 + h )|0;
10945 }
10946
10947 function _core_heap ( offset ) {
10948 offset = offset|0;
10949
10950 _core(
10951 HEAP[offset|0]<<24 | HEAP[offset|1]<<16 | HEAP[offset|2]<<8 | HEAP[offset|3],
10952 HEAP[offset|4]<<24 | HEAP[offset|5]<<16 | HEAP[offset|6]<<8 | HEAP[offset|7],
10953 HEAP[offset|8]<<24 | HEAP[offset|9]<<16 | HEAP[offset|10]<<8 | HEAP[offset|11],
10954 HEAP[offset|12]<<24 | HEAP[offset|13]<<16 | HEAP[offset|14]<<8 | HEAP[offset|15],
10955 HEAP[offset|16]<<24 | HEAP[offset|17]<<16 | HEAP[offset|18]<<8 | HEAP[offset|19],
10956 HEAP[offset|20]<<24 | HEAP[offset|21]<<16 | HEAP[offset|22]<<8 | HEAP[offset|23],
10957 HEAP[offset|24]<<24 | HEAP[offset|25]<<16 | HEAP[offset|26]<<8 | HEAP[offset|27],
10958 HEAP[offset|28]<<24 | HEAP[offset|29]<<16 | HEAP[offset|30]<<8 | HEAP[offset|31],
10959 HEAP[offset|32]<<24 | HEAP[offset|33]<<16 | HEAP[offset|34]<<8 | HEAP[offset|35],
10960 HEAP[offset|36]<<24 | HEAP[offset|37]<<16 | HEAP[offset|38]<<8 | HEAP[offset|39],
10961 HEAP[offset|40]<<24 | HEAP[offset|41]<<16 | HEAP[offset|42]<<8 | HEAP[offset|43],
10962 HEAP[offset|44]<<24 | HEAP[offset|45]<<16 | HEAP[offset|46]<<8 | HEAP[offset|47],
10963 HEAP[offset|48]<<24 | HEAP[offset|49]<<16 | HEAP[offset|50]<<8 | HEAP[offset|51],
10964 HEAP[offset|52]<<24 | HEAP[offset|53]<<16 | HEAP[offset|54]<<8 | HEAP[offset|55],
10965 HEAP[offset|56]<<24 | HEAP[offset|57]<<16 | HEAP[offset|58]<<8 | HEAP[offset|59],
10966 HEAP[offset|60]<<24 | HEAP[offset|61]<<16 | HEAP[offset|62]<<8 | HEAP[offset|63]
10967 );
10968 }
10969
10970 // offset — multiple of 32
10971 function _state_to_heap ( output ) {
10972 output = output|0;
10973
10974 HEAP[output|0] = H0>>>24;
10975 HEAP[output|1] = H0>>>16&255;
10976 HEAP[output|2] = H0>>>8&255;
10977 HEAP[output|3] = H0&255;
10978 HEAP[output|4] = H1>>>24;
10979 HEAP[output|5] = H1>>>16&255;
10980 HEAP[output|6] = H1>>>8&255;
10981 HEAP[output|7] = H1&255;
10982 HEAP[output|8] = H2>>>24;
10983 HEAP[output|9] = H2>>>16&255;
10984 HEAP[output|10] = H2>>>8&255;
10985 HEAP[output|11] = H2&255;
10986 HEAP[output|12] = H3>>>24;
10987 HEAP[output|13] = H3>>>16&255;
10988 HEAP[output|14] = H3>>>8&255;
10989 HEAP[output|15] = H3&255;
10990 HEAP[output|16] = H4>>>24;
10991 HEAP[output|17] = H4>>>16&255;
10992 HEAP[output|18] = H4>>>8&255;
10993 HEAP[output|19] = H4&255;
10994 HEAP[output|20] = H5>>>24;
10995 HEAP[output|21] = H5>>>16&255;
10996 HEAP[output|22] = H5>>>8&255;
10997 HEAP[output|23] = H5&255;
10998 HEAP[output|24] = H6>>>24;
10999 HEAP[output|25] = H6>>>16&255;
11000 HEAP[output|26] = H6>>>8&255;
11001 HEAP[output|27] = H6&255;
11002 HEAP[output|28] = H7>>>24;
11003 HEAP[output|29] = H7>>>16&255;
11004 HEAP[output|30] = H7>>>8&255;
11005 HEAP[output|31] = H7&255;
11006 }
11007
11008 function reset () {
11009 H0 = 0x6a09e667;
11010 H1 = 0xbb67ae85;
11011 H2 = 0x3c6ef372;
11012 H3 = 0xa54ff53a;
11013 H4 = 0x510e527f;
11014 H5 = 0x9b05688c;
11015 H6 = 0x1f83d9ab;
11016 H7 = 0x5be0cd19;
11017 TOTAL0 = TOTAL1 = 0;
11018 }
11019
11020 function init ( h0, h1, h2, h3, h4, h5, h6, h7, total0, total1 ) {
11021 h0 = h0|0;
11022 h1 = h1|0;
11023 h2 = h2|0;
11024 h3 = h3|0;
11025 h4 = h4|0;
11026 h5 = h5|0;
11027 h6 = h6|0;
11028 h7 = h7|0;
11029 total0 = total0|0;
11030 total1 = total1|0;
11031
11032 H0 = h0;
11033 H1 = h1;
11034 H2 = h2;
11035 H3 = h3;
11036 H4 = h4;
11037 H5 = h5;
11038 H6 = h6;
11039 H7 = h7;
11040 TOTAL0 = total0;
11041 TOTAL1 = total1;
11042 }
11043
11044 // offset — multiple of 64
11045 function process ( offset, length ) {
11046 offset = offset|0;
11047 length = length|0;
11048
11049 var hashed = 0;
11050
11051 if ( offset & 63 )
11052 return -1;
11053
11054 while ( (length|0) >= 64 ) {
11055 _core_heap(offset);
11056
11057 offset = ( offset + 64 )|0;
11058 length = ( length - 64 )|0;
11059
11060 hashed = ( hashed + 64 )|0;
11061 }
11062
11063 TOTAL0 = ( TOTAL0 + hashed )|0;
11064 if ( TOTAL0>>>0 < hashed>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0;
11065
11066 return hashed|0;
11067 }
11068
11069 // offset — multiple of 64
11070 // output — multiple of 32
11071 function finish ( offset, length, output ) {
11072 offset = offset|0;
11073 length = length|0;
11074 output = output|0;
11075
11076 var hashed = 0,
11077 i = 0;
11078
11079 if ( offset & 63 )
11080 return -1;
11081
11082 if ( ~output )
11083 if ( output & 31 )
11084 return -1;
11085
11086 if ( (length|0) >= 64 ) {
11087 hashed = process( offset, length )|0;
11088 if ( (hashed|0) == -1 )
11089 return -1;
11090
11091 offset = ( offset + hashed )|0;
11092 length = ( length - hashed )|0;
11093 }
11094
11095 hashed = ( hashed + length )|0;
11096 TOTAL0 = ( TOTAL0 + length )|0;
11097 if ( TOTAL0>>>0 < length>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0;
11098
11099 HEAP[offset|length] = 0x80;
11100
11101 if ( (length|0) >= 56 ) {
11102 for ( i = (length+1)|0; (i|0) < 64; i = (i+1)|0 )
11103 HEAP[offset|i] = 0x00;
11104
11105 _core_heap(offset);
11106
11107 length = 0;
11108
11109 HEAP[offset|0] = 0;
11110 }
11111
11112 for ( i = (length+1)|0; (i|0) < 59; i = (i+1)|0 )
11113 HEAP[offset|i] = 0;
11114
11115 HEAP[offset|56] = TOTAL1>>>21&255;
11116 HEAP[offset|57] = TOTAL1>>>13&255;
11117 HEAP[offset|58] = TOTAL1>>>5&255;
11118 HEAP[offset|59] = TOTAL1<<3&255 | TOTAL0>>>29;
11119 HEAP[offset|60] = TOTAL0>>>21&255;
11120 HEAP[offset|61] = TOTAL0>>>13&255;
11121 HEAP[offset|62] = TOTAL0>>>5&255;
11122 HEAP[offset|63] = TOTAL0<<3&255;
11123 _core_heap(offset);
11124
11125 if ( ~output )
11126 _state_to_heap(output);
11127
11128 return hashed|0;
11129 }
11130
11131 function hmac_reset () {
11132 H0 = I0;
11133 H1 = I1;
11134 H2 = I2;
11135 H3 = I3;
11136 H4 = I4;
11137 H5 = I5;
11138 H6 = I6;
11139 H7 = I7;
11140 TOTAL0 = 64;
11141 TOTAL1 = 0;
11142 }
11143
11144 function _hmac_opad () {
11145 H0 = O0;
11146 H1 = O1;
11147 H2 = O2;
11148 H3 = O3;
11149 H4 = O4;
11150 H5 = O5;
11151 H6 = O6;
11152 H7 = O7;
11153 TOTAL0 = 64;
11154 TOTAL1 = 0;
11155 }
11156
11157 function hmac_init ( p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 ) {
11158 p0 = p0|0;
11159 p1 = p1|0;
11160 p2 = p2|0;
11161 p3 = p3|0;
11162 p4 = p4|0;
11163 p5 = p5|0;
11164 p6 = p6|0;
11165 p7 = p7|0;
11166 p8 = p8|0;
11167 p9 = p9|0;
11168 p10 = p10|0;
11169 p11 = p11|0;
11170 p12 = p12|0;
11171 p13 = p13|0;
11172 p14 = p14|0;
11173 p15 = p15|0;
11174
11175 // opad
11176 reset();
11177 _core(
11178 p0 ^ 0x5c5c5c5c,
11179 p1 ^ 0x5c5c5c5c,
11180 p2 ^ 0x5c5c5c5c,
11181 p3 ^ 0x5c5c5c5c,
11182 p4 ^ 0x5c5c5c5c,
11183 p5 ^ 0x5c5c5c5c,
11184 p6 ^ 0x5c5c5c5c,
11185 p7 ^ 0x5c5c5c5c,
11186 p8 ^ 0x5c5c5c5c,
11187 p9 ^ 0x5c5c5c5c,
11188 p10 ^ 0x5c5c5c5c,
11189 p11 ^ 0x5c5c5c5c,
11190 p12 ^ 0x5c5c5c5c,
11191 p13 ^ 0x5c5c5c5c,
11192 p14 ^ 0x5c5c5c5c,
11193 p15 ^ 0x5c5c5c5c
11194 );
11195 O0 = H0;
11196 O1 = H1;
11197 O2 = H2;
11198 O3 = H3;
11199 O4 = H4;
11200 O5 = H5;
11201 O6 = H6;
11202 O7 = H7;
11203
11204 // ipad
11205 reset();
11206 _core(
11207 p0 ^ 0x36363636,
11208 p1 ^ 0x36363636,
11209 p2 ^ 0x36363636,
11210 p3 ^ 0x36363636,
11211 p4 ^ 0x36363636,
11212 p5 ^ 0x36363636,
11213 p6 ^ 0x36363636,
11214 p7 ^ 0x36363636,
11215 p8 ^ 0x36363636,
11216 p9 ^ 0x36363636,
11217 p10 ^ 0x36363636,
11218 p11 ^ 0x36363636,
11219 p12 ^ 0x36363636,
11220 p13 ^ 0x36363636,
11221 p14 ^ 0x36363636,
11222 p15 ^ 0x36363636
11223 );
11224 I0 = H0;
11225 I1 = H1;
11226 I2 = H2;
11227 I3 = H3;
11228 I4 = H4;
11229 I5 = H5;
11230 I6 = H6;
11231 I7 = H7;
11232
11233 TOTAL0 = 64;
11234 TOTAL1 = 0;
11235 }
11236
11237 // offset — multiple of 64
11238 // output — multiple of 32
11239 function hmac_finish ( offset, length, output ) {
11240 offset = offset|0;
11241 length = length|0;
11242 output = output|0;
11243
11244 var t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
11245 hashed = 0;
11246
11247 if ( offset & 63 )
11248 return -1;
11249
11250 if ( ~output )
11251 if ( output & 31 )
11252 return -1;
11253
11254 hashed = finish( offset, length, -1 )|0;
11255 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
11256
11257 _hmac_opad();
11258 _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 );
11259
11260 if ( ~output )
11261 _state_to_heap(output);
11262
11263 return hashed|0;
11264 }
11265
11266 // salt is assumed to be already processed
11267 // offset — multiple of 64
11268 // output — multiple of 32
11269 function pbkdf2_generate_block ( offset, length, block, count, output ) {
11270 offset = offset|0;
11271 length = length|0;
11272 block = block|0;
11273 count = count|0;
11274 output = output|0;
11275
11276 var h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0, h7 = 0,
11277 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0;
11278
11279 if ( offset & 63 )
11280 return -1;
11281
11282 if ( ~output )
11283 if ( output & 31 )
11284 return -1;
11285
11286 // pad block number into heap
11287 // FIXME probable OOB write
11288 HEAP[(offset+length)|0] = block>>>24;
11289 HEAP[(offset+length+1)|0] = block>>>16&255;
11290 HEAP[(offset+length+2)|0] = block>>>8&255;
11291 HEAP[(offset+length+3)|0] = block&255;
11292
11293 // finish first iteration
11294 hmac_finish( offset, (length+4)|0, -1 )|0;
11295 h0 = t0 = H0, h1 = t1 = H1, h2 = t2 = H2, h3 = t3 = H3, h4 = t4 = H4, h5 = t5 = H5, h6 = t6 = H6, h7 = t7 = H7;
11296 count = (count-1)|0;
11297
11298 // perform the rest iterations
11299 while ( (count|0) > 0 ) {
11300 hmac_reset();
11301 _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 );
11302 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
11303
11304 _hmac_opad();
11305 _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 );
11306 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
11307
11308 h0 = h0 ^ H0;
11309 h1 = h1 ^ H1;
11310 h2 = h2 ^ H2;
11311 h3 = h3 ^ H3;
11312 h4 = h4 ^ H4;
11313 h5 = h5 ^ H5;
11314 h6 = h6 ^ H6;
11315 h7 = h7 ^ H7;
11316
11317 count = (count-1)|0;
11318 }
11319
11320 H0 = h0;
11321 H1 = h1;
11322 H2 = h2;
11323 H3 = h3;
11324 H4 = h4;
11325 H5 = h5;
11326 H6 = h6;
11327 H7 = h7;
11328
11329 if ( ~output )
11330 _state_to_heap(output);
11331
11332 return 0;
11333 }
11334
11335 return {
11336 // SHA256
11337 reset: reset,
11338 init: init,
11339 process: process,
11340 finish: finish,
11341
11342 // HMAC-SHA256
11343 hmac_reset: hmac_reset,
11344 hmac_init: hmac_init,
11345 hmac_finish: hmac_finish,
11346
11347 // PBKDF2-HMAC-SHA256
11348 pbkdf2_generate_block: pbkdf2_generate_block
11349 }
11350};
11351
11352const _sha256_block_size = 64;
11353const _sha256_hash_size = 32;
11354const heap_pool$2 = [];
11355const asm_pool$2 = [];
11356class Sha256 extends Hash {
11357 constructor() {
11358 super();
11359 this.NAME = 'sha256';
11360 this.BLOCK_SIZE = _sha256_block_size;
11361 this.HASH_SIZE = _sha256_hash_size;
11362 this.acquire_asm();
11363 }
11364 acquire_asm() {
11365 if (this.heap === undefined || this.asm === undefined) {
11366 this.heap = heap_pool$2.pop() || _heap_init();
11367 this.asm = asm_pool$2.pop() || sha256_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
11368 this.reset();
11369 }
11370 return { heap: this.heap, asm: this.asm };
11371 }
11372 release_asm() {
11373 if (this.heap !== undefined && this.asm !== undefined) {
11374 heap_pool$2.push(this.heap);
11375 asm_pool$2.push(this.asm);
11376 }
11377 this.heap = undefined;
11378 this.asm = undefined;
11379 }
11380 static bytes(data) {
11381 return new Sha256().process(data).finish().result;
11382 }
11383}
11384Sha256.NAME = 'sha256';
11385
11386var minimalisticAssert = assert$1;
11387
11388function assert$1(val, msg) {
11389 if (!val)
11390 throw new Error(msg || 'Assertion failed');
11391}
11392
11393assert$1.equal = function assertEqual(l, r, msg) {
11394 if (l != r)
11395 throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
11396};
11397
11398var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
11399
11400function createCommonjsModule(fn, module) {
11401 return module = { exports: {} }, fn(module, module.exports), module.exports;
11402}
11403
11404function commonjsRequire () {
11405 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
11406}
11407
11408var inherits_browser = createCommonjsModule(function (module) {
11409if (typeof Object.create === 'function') {
11410 // implementation from standard node.js 'util' module
11411 module.exports = function inherits(ctor, superCtor) {
11412 ctor.super_ = superCtor;
11413 ctor.prototype = Object.create(superCtor.prototype, {
11414 constructor: {
11415 value: ctor,
11416 enumerable: false,
11417 writable: true,
11418 configurable: true
11419 }
11420 });
11421 };
11422} else {
11423 // old school shim for old browsers
11424 module.exports = function inherits(ctor, superCtor) {
11425 ctor.super_ = superCtor;
11426 var TempCtor = function () {};
11427 TempCtor.prototype = superCtor.prototype;
11428 ctor.prototype = new TempCtor();
11429 ctor.prototype.constructor = ctor;
11430 };
11431}
11432});
11433
11434var inherits_1 = inherits_browser;
11435
11436function toArray(msg, enc) {
11437 if (Array.isArray(msg))
11438 return msg.slice();
11439 if (!msg)
11440 return [];
11441 var res = [];
11442 if (typeof msg === 'string') {
11443 if (!enc) {
11444 for (var i = 0; i < msg.length; i++) {
11445 var c = msg.charCodeAt(i);
11446 var hi = c >> 8;
11447 var lo = c & 0xff;
11448 if (hi)
11449 res.push(hi, lo);
11450 else
11451 res.push(lo);
11452 }
11453 } else if (enc === 'hex') {
11454 msg = msg.replace(/[^a-z0-9]+/ig, '');
11455 if (msg.length % 2 !== 0)
11456 msg = '0' + msg;
11457 for (i = 0; i < msg.length; i += 2)
11458 res.push(parseInt(msg[i] + msg[i + 1], 16));
11459 }
11460 } else {
11461 for (i = 0; i < msg.length; i++)
11462 res[i] = msg[i] | 0;
11463 }
11464 return res;
11465}
11466var toArray_1 = toArray;
11467
11468function toHex(msg) {
11469 var res = '';
11470 for (var i = 0; i < msg.length; i++)
11471 res += zero2(msg[i].toString(16));
11472 return res;
11473}
11474var toHex_1 = toHex;
11475
11476function htonl(w) {
11477 var res = (w >>> 24) |
11478 ((w >>> 8) & 0xff00) |
11479 ((w << 8) & 0xff0000) |
11480 ((w & 0xff) << 24);
11481 return res >>> 0;
11482}
11483var htonl_1 = htonl;
11484
11485function toHex32(msg, endian) {
11486 var res = '';
11487 for (var i = 0; i < msg.length; i++) {
11488 var w = msg[i];
11489 if (endian === 'little')
11490 w = htonl(w);
11491 res += zero8(w.toString(16));
11492 }
11493 return res;
11494}
11495var toHex32_1 = toHex32;
11496
11497function zero2(word) {
11498 if (word.length === 1)
11499 return '0' + word;
11500 else
11501 return word;
11502}
11503var zero2_1 = zero2;
11504
11505function zero8(word) {
11506 if (word.length === 7)
11507 return '0' + word;
11508 else if (word.length === 6)
11509 return '00' + word;
11510 else if (word.length === 5)
11511 return '000' + word;
11512 else if (word.length === 4)
11513 return '0000' + word;
11514 else if (word.length === 3)
11515 return '00000' + word;
11516 else if (word.length === 2)
11517 return '000000' + word;
11518 else if (word.length === 1)
11519 return '0000000' + word;
11520 else
11521 return word;
11522}
11523var zero8_1 = zero8;
11524
11525function join32(msg, start, end, endian) {
11526 var len = end - start;
11527 minimalisticAssert(len % 4 === 0);
11528 var res = new Array(len / 4);
11529 for (var i = 0, k = start; i < res.length; i++, k += 4) {
11530 var w;
11531 if (endian === 'big')
11532 w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
11533 else
11534 w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
11535 res[i] = w >>> 0;
11536 }
11537 return res;
11538}
11539var join32_1 = join32;
11540
11541function split32(msg, endian) {
11542 var res = new Array(msg.length * 4);
11543 for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
11544 var m = msg[i];
11545 if (endian === 'big') {
11546 res[k] = m >>> 24;
11547 res[k + 1] = (m >>> 16) & 0xff;
11548 res[k + 2] = (m >>> 8) & 0xff;
11549 res[k + 3] = m & 0xff;
11550 } else {
11551 res[k + 3] = m >>> 24;
11552 res[k + 2] = (m >>> 16) & 0xff;
11553 res[k + 1] = (m >>> 8) & 0xff;
11554 res[k] = m & 0xff;
11555 }
11556 }
11557 return res;
11558}
11559var split32_1 = split32;
11560
11561function rotr32(w, b) {
11562 return (w >>> b) | (w << (32 - b));
11563}
11564var rotr32_1 = rotr32;
11565
11566function rotl32(w, b) {
11567 return (w << b) | (w >>> (32 - b));
11568}
11569var rotl32_1 = rotl32;
11570
11571function sum32(a, b) {
11572 return (a + b) >>> 0;
11573}
11574var sum32_1 = sum32;
11575
11576function sum32_3(a, b, c) {
11577 return (a + b + c) >>> 0;
11578}
11579var sum32_3_1 = sum32_3;
11580
11581function sum32_4(a, b, c, d) {
11582 return (a + b + c + d) >>> 0;
11583}
11584var sum32_4_1 = sum32_4;
11585
11586function sum32_5(a, b, c, d, e) {
11587 return (a + b + c + d + e) >>> 0;
11588}
11589var sum32_5_1 = sum32_5;
11590
11591function sum64(buf, pos, ah, al) {
11592 var bh = buf[pos];
11593 var bl = buf[pos + 1];
11594
11595 var lo = (al + bl) >>> 0;
11596 var hi = (lo < al ? 1 : 0) + ah + bh;
11597 buf[pos] = hi >>> 0;
11598 buf[pos + 1] = lo;
11599}
11600var sum64_1 = sum64;
11601
11602function sum64_hi(ah, al, bh, bl) {
11603 var lo = (al + bl) >>> 0;
11604 var hi = (lo < al ? 1 : 0) + ah + bh;
11605 return hi >>> 0;
11606}
11607var sum64_hi_1 = sum64_hi;
11608
11609function sum64_lo(ah, al, bh, bl) {
11610 var lo = al + bl;
11611 return lo >>> 0;
11612}
11613var sum64_lo_1 = sum64_lo;
11614
11615function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
11616 var carry = 0;
11617 var lo = al;
11618 lo = (lo + bl) >>> 0;
11619 carry += lo < al ? 1 : 0;
11620 lo = (lo + cl) >>> 0;
11621 carry += lo < cl ? 1 : 0;
11622 lo = (lo + dl) >>> 0;
11623 carry += lo < dl ? 1 : 0;
11624
11625 var hi = ah + bh + ch + dh + carry;
11626 return hi >>> 0;
11627}
11628var sum64_4_hi_1 = sum64_4_hi;
11629
11630function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
11631 var lo = al + bl + cl + dl;
11632 return lo >>> 0;
11633}
11634var sum64_4_lo_1 = sum64_4_lo;
11635
11636function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
11637 var carry = 0;
11638 var lo = al;
11639 lo = (lo + bl) >>> 0;
11640 carry += lo < al ? 1 : 0;
11641 lo = (lo + cl) >>> 0;
11642 carry += lo < cl ? 1 : 0;
11643 lo = (lo + dl) >>> 0;
11644 carry += lo < dl ? 1 : 0;
11645 lo = (lo + el) >>> 0;
11646 carry += lo < el ? 1 : 0;
11647
11648 var hi = ah + bh + ch + dh + eh + carry;
11649 return hi >>> 0;
11650}
11651var sum64_5_hi_1 = sum64_5_hi;
11652
11653function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
11654 var lo = al + bl + cl + dl + el;
11655
11656 return lo >>> 0;
11657}
11658var sum64_5_lo_1 = sum64_5_lo;
11659
11660function rotr64_hi(ah, al, num) {
11661 var r = (al << (32 - num)) | (ah >>> num);
11662 return r >>> 0;
11663}
11664var rotr64_hi_1 = rotr64_hi;
11665
11666function rotr64_lo(ah, al, num) {
11667 var r = (ah << (32 - num)) | (al >>> num);
11668 return r >>> 0;
11669}
11670var rotr64_lo_1 = rotr64_lo;
11671
11672function shr64_hi(ah, al, num) {
11673 return ah >>> num;
11674}
11675var shr64_hi_1 = shr64_hi;
11676
11677function shr64_lo(ah, al, num) {
11678 var r = (ah << (32 - num)) | (al >>> num);
11679 return r >>> 0;
11680}
11681var shr64_lo_1 = shr64_lo;
11682
11683var utils = {
11684 inherits: inherits_1,
11685 toArray: toArray_1,
11686 toHex: toHex_1,
11687 htonl: htonl_1,
11688 toHex32: toHex32_1,
11689 zero2: zero2_1,
11690 zero8: zero8_1,
11691 join32: join32_1,
11692 split32: split32_1,
11693 rotr32: rotr32_1,
11694 rotl32: rotl32_1,
11695 sum32: sum32_1,
11696 sum32_3: sum32_3_1,
11697 sum32_4: sum32_4_1,
11698 sum32_5: sum32_5_1,
11699 sum64: sum64_1,
11700 sum64_hi: sum64_hi_1,
11701 sum64_lo: sum64_lo_1,
11702 sum64_4_hi: sum64_4_hi_1,
11703 sum64_4_lo: sum64_4_lo_1,
11704 sum64_5_hi: sum64_5_hi_1,
11705 sum64_5_lo: sum64_5_lo_1,
11706 rotr64_hi: rotr64_hi_1,
11707 rotr64_lo: rotr64_lo_1,
11708 shr64_hi: shr64_hi_1,
11709 shr64_lo: shr64_lo_1
11710};
11711
11712function BlockHash() {
11713 this.pending = null;
11714 this.pendingTotal = 0;
11715 this.blockSize = this.constructor.blockSize;
11716 this.outSize = this.constructor.outSize;
11717 this.hmacStrength = this.constructor.hmacStrength;
11718 this.padLength = this.constructor.padLength / 8;
11719 this.endian = 'big';
11720
11721 this._delta8 = this.blockSize / 8;
11722 this._delta32 = this.blockSize / 32;
11723}
11724var BlockHash_1 = BlockHash;
11725
11726BlockHash.prototype.update = function update(msg, enc) {
11727 // Convert message to array, pad it, and join into 32bit blocks
11728 msg = utils.toArray(msg, enc);
11729 if (!this.pending)
11730 this.pending = msg;
11731 else
11732 this.pending = this.pending.concat(msg);
11733 this.pendingTotal += msg.length;
11734
11735 // Enough data, try updating
11736 if (this.pending.length >= this._delta8) {
11737 msg = this.pending;
11738
11739 // Process pending data in blocks
11740 var r = msg.length % this._delta8;
11741 this.pending = msg.slice(msg.length - r, msg.length);
11742 if (this.pending.length === 0)
11743 this.pending = null;
11744
11745 msg = utils.join32(msg, 0, msg.length - r, this.endian);
11746 for (var i = 0; i < msg.length; i += this._delta32)
11747 this._update(msg, i, i + this._delta32);
11748 }
11749
11750 return this;
11751};
11752
11753BlockHash.prototype.digest = function digest(enc) {
11754 this.update(this._pad());
11755 minimalisticAssert(this.pending === null);
11756
11757 return this._digest(enc);
11758};
11759
11760BlockHash.prototype._pad = function pad() {
11761 var len = this.pendingTotal;
11762 var bytes = this._delta8;
11763 var k = bytes - ((len + this.padLength) % bytes);
11764 var res = new Array(k + this.padLength);
11765 res[0] = 0x80;
11766 for (var i = 1; i < k; i++)
11767 res[i] = 0;
11768
11769 // Append length
11770 len <<= 3;
11771 if (this.endian === 'big') {
11772 for (var t = 8; t < this.padLength; t++)
11773 res[i++] = 0;
11774
11775 res[i++] = 0;
11776 res[i++] = 0;
11777 res[i++] = 0;
11778 res[i++] = 0;
11779 res[i++] = (len >>> 24) & 0xff;
11780 res[i++] = (len >>> 16) & 0xff;
11781 res[i++] = (len >>> 8) & 0xff;
11782 res[i++] = len & 0xff;
11783 } else {
11784 res[i++] = len & 0xff;
11785 res[i++] = (len >>> 8) & 0xff;
11786 res[i++] = (len >>> 16) & 0xff;
11787 res[i++] = (len >>> 24) & 0xff;
11788 res[i++] = 0;
11789 res[i++] = 0;
11790 res[i++] = 0;
11791 res[i++] = 0;
11792
11793 for (t = 8; t < this.padLength; t++)
11794 res[i++] = 0;
11795 }
11796
11797 return res;
11798};
11799
11800var common = {
11801 BlockHash: BlockHash_1
11802};
11803
11804var rotr32$1 = utils.rotr32;
11805
11806function ft_1(s, x, y, z) {
11807 if (s === 0)
11808 return ch32(x, y, z);
11809 if (s === 1 || s === 3)
11810 return p32(x, y, z);
11811 if (s === 2)
11812 return maj32(x, y, z);
11813}
11814var ft_1_1 = ft_1;
11815
11816function ch32(x, y, z) {
11817 return (x & y) ^ ((~x) & z);
11818}
11819var ch32_1 = ch32;
11820
11821function maj32(x, y, z) {
11822 return (x & y) ^ (x & z) ^ (y & z);
11823}
11824var maj32_1 = maj32;
11825
11826function p32(x, y, z) {
11827 return x ^ y ^ z;
11828}
11829var p32_1 = p32;
11830
11831function s0_256(x) {
11832 return rotr32$1(x, 2) ^ rotr32$1(x, 13) ^ rotr32$1(x, 22);
11833}
11834var s0_256_1 = s0_256;
11835
11836function s1_256(x) {
11837 return rotr32$1(x, 6) ^ rotr32$1(x, 11) ^ rotr32$1(x, 25);
11838}
11839var s1_256_1 = s1_256;
11840
11841function g0_256(x) {
11842 return rotr32$1(x, 7) ^ rotr32$1(x, 18) ^ (x >>> 3);
11843}
11844var g0_256_1 = g0_256;
11845
11846function g1_256(x) {
11847 return rotr32$1(x, 17) ^ rotr32$1(x, 19) ^ (x >>> 10);
11848}
11849var g1_256_1 = g1_256;
11850
11851var common$1 = {
11852 ft_1: ft_1_1,
11853 ch32: ch32_1,
11854 maj32: maj32_1,
11855 p32: p32_1,
11856 s0_256: s0_256_1,
11857 s1_256: s1_256_1,
11858 g0_256: g0_256_1,
11859 g1_256: g1_256_1
11860};
11861
11862var sum32$1 = utils.sum32;
11863var sum32_4$1 = utils.sum32_4;
11864var sum32_5$1 = utils.sum32_5;
11865var ch32$1 = common$1.ch32;
11866var maj32$1 = common$1.maj32;
11867var s0_256$1 = common$1.s0_256;
11868var s1_256$1 = common$1.s1_256;
11869var g0_256$1 = common$1.g0_256;
11870var g1_256$1 = common$1.g1_256;
11871
11872var BlockHash$1 = common.BlockHash;
11873
11874var sha256_K = [
11875 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
11876 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
11877 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
11878 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
11879 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
11880 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
11881 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
11882 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
11883 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
11884 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
11885 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
11886 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
11887 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
11888 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
11889 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
11890 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
11891];
11892
11893function SHA256() {
11894 if (!(this instanceof SHA256))
11895 return new SHA256();
11896
11897 BlockHash$1.call(this);
11898 this.h = [
11899 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
11900 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
11901 ];
11902 this.k = sha256_K;
11903 this.W = new Array(64);
11904}
11905utils.inherits(SHA256, BlockHash$1);
11906var _256 = SHA256;
11907
11908SHA256.blockSize = 512;
11909SHA256.outSize = 256;
11910SHA256.hmacStrength = 192;
11911SHA256.padLength = 64;
11912
11913SHA256.prototype._update = function _update(msg, start) {
11914 var W = this.W;
11915
11916 for (var i = 0; i < 16; i++)
11917 W[i] = msg[start + i];
11918 for (; i < W.length; i++)
11919 W[i] = sum32_4$1(g1_256$1(W[i - 2]), W[i - 7], g0_256$1(W[i - 15]), W[i - 16]);
11920
11921 var a = this.h[0];
11922 var b = this.h[1];
11923 var c = this.h[2];
11924 var d = this.h[3];
11925 var e = this.h[4];
11926 var f = this.h[5];
11927 var g = this.h[6];
11928 var h = this.h[7];
11929
11930 minimalisticAssert(this.k.length === W.length);
11931 for (i = 0; i < W.length; i++) {
11932 var T1 = sum32_5$1(h, s1_256$1(e), ch32$1(e, f, g), this.k[i], W[i]);
11933 var T2 = sum32$1(s0_256$1(a), maj32$1(a, b, c));
11934 h = g;
11935 g = f;
11936 f = e;
11937 e = sum32$1(d, T1);
11938 d = c;
11939 c = b;
11940 b = a;
11941 a = sum32$1(T1, T2);
11942 }
11943
11944 this.h[0] = sum32$1(this.h[0], a);
11945 this.h[1] = sum32$1(this.h[1], b);
11946 this.h[2] = sum32$1(this.h[2], c);
11947 this.h[3] = sum32$1(this.h[3], d);
11948 this.h[4] = sum32$1(this.h[4], e);
11949 this.h[5] = sum32$1(this.h[5], f);
11950 this.h[6] = sum32$1(this.h[6], g);
11951 this.h[7] = sum32$1(this.h[7], h);
11952};
11953
11954SHA256.prototype._digest = function digest(enc) {
11955 if (enc === 'hex')
11956 return utils.toHex32(this.h, 'big');
11957 else
11958 return utils.split32(this.h, 'big');
11959};
11960
11961function SHA224() {
11962 if (!(this instanceof SHA224))
11963 return new SHA224();
11964
11965 _256.call(this);
11966 this.h = [
11967 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
11968 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
11969}
11970utils.inherits(SHA224, _256);
11971var _224 = SHA224;
11972
11973SHA224.blockSize = 512;
11974SHA224.outSize = 224;
11975SHA224.hmacStrength = 192;
11976SHA224.padLength = 64;
11977
11978SHA224.prototype._digest = function digest(enc) {
11979 // Just truncate output
11980 if (enc === 'hex')
11981 return utils.toHex32(this.h.slice(0, 7), 'big');
11982 else
11983 return utils.split32(this.h.slice(0, 7), 'big');
11984};
11985
11986var rotr64_hi$1 = utils.rotr64_hi;
11987var rotr64_lo$1 = utils.rotr64_lo;
11988var shr64_hi$1 = utils.shr64_hi;
11989var shr64_lo$1 = utils.shr64_lo;
11990var sum64$1 = utils.sum64;
11991var sum64_hi$1 = utils.sum64_hi;
11992var sum64_lo$1 = utils.sum64_lo;
11993var sum64_4_hi$1 = utils.sum64_4_hi;
11994var sum64_4_lo$1 = utils.sum64_4_lo;
11995var sum64_5_hi$1 = utils.sum64_5_hi;
11996var sum64_5_lo$1 = utils.sum64_5_lo;
11997
11998var BlockHash$2 = common.BlockHash;
11999
12000var sha512_K = [
12001 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
12002 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
12003 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
12004 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
12005 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
12006 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
12007 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
12008 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
12009 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
12010 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
12011 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
12012 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
12013 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
12014 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
12015 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
12016 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
12017 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
12018 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
12019 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
12020 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
12021 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
12022 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
12023 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
12024 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
12025 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
12026 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
12027 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
12028 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
12029 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
12030 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
12031 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
12032 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
12033 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
12034 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
12035 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
12036 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
12037 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
12038 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
12039 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
12040 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
12041];
12042
12043function SHA512() {
12044 if (!(this instanceof SHA512))
12045 return new SHA512();
12046
12047 BlockHash$2.call(this);
12048 this.h = [
12049 0x6a09e667, 0xf3bcc908,
12050 0xbb67ae85, 0x84caa73b,
12051 0x3c6ef372, 0xfe94f82b,
12052 0xa54ff53a, 0x5f1d36f1,
12053 0x510e527f, 0xade682d1,
12054 0x9b05688c, 0x2b3e6c1f,
12055 0x1f83d9ab, 0xfb41bd6b,
12056 0x5be0cd19, 0x137e2179 ];
12057 this.k = sha512_K;
12058 this.W = new Array(160);
12059}
12060utils.inherits(SHA512, BlockHash$2);
12061var _512 = SHA512;
12062
12063SHA512.blockSize = 1024;
12064SHA512.outSize = 512;
12065SHA512.hmacStrength = 192;
12066SHA512.padLength = 128;
12067
12068SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
12069 var W = this.W;
12070
12071 // 32 x 32bit words
12072 for (var i = 0; i < 32; i++)
12073 W[i] = msg[start + i];
12074 for (; i < W.length; i += 2) {
12075 var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
12076 var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
12077 var c1_hi = W[i - 14]; // i - 7
12078 var c1_lo = W[i - 13];
12079 var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
12080 var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
12081 var c3_hi = W[i - 32]; // i - 16
12082 var c3_lo = W[i - 31];
12083
12084 W[i] = sum64_4_hi$1(
12085 c0_hi, c0_lo,
12086 c1_hi, c1_lo,
12087 c2_hi, c2_lo,
12088 c3_hi, c3_lo);
12089 W[i + 1] = sum64_4_lo$1(
12090 c0_hi, c0_lo,
12091 c1_hi, c1_lo,
12092 c2_hi, c2_lo,
12093 c3_hi, c3_lo);
12094 }
12095};
12096
12097SHA512.prototype._update = function _update(msg, start) {
12098 this._prepareBlock(msg, start);
12099
12100 var W = this.W;
12101
12102 var ah = this.h[0];
12103 var al = this.h[1];
12104 var bh = this.h[2];
12105 var bl = this.h[3];
12106 var ch = this.h[4];
12107 var cl = this.h[5];
12108 var dh = this.h[6];
12109 var dl = this.h[7];
12110 var eh = this.h[8];
12111 var el = this.h[9];
12112 var fh = this.h[10];
12113 var fl = this.h[11];
12114 var gh = this.h[12];
12115 var gl = this.h[13];
12116 var hh = this.h[14];
12117 var hl = this.h[15];
12118
12119 minimalisticAssert(this.k.length === W.length);
12120 for (var i = 0; i < W.length; i += 2) {
12121 var c0_hi = hh;
12122 var c0_lo = hl;
12123 var c1_hi = s1_512_hi(eh, el);
12124 var c1_lo = s1_512_lo(eh, el);
12125 var c2_hi = ch64_hi(eh, el, fh, fl, gh);
12126 var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
12127 var c3_hi = this.k[i];
12128 var c3_lo = this.k[i + 1];
12129 var c4_hi = W[i];
12130 var c4_lo = W[i + 1];
12131
12132 var T1_hi = sum64_5_hi$1(
12133 c0_hi, c0_lo,
12134 c1_hi, c1_lo,
12135 c2_hi, c2_lo,
12136 c3_hi, c3_lo,
12137 c4_hi, c4_lo);
12138 var T1_lo = sum64_5_lo$1(
12139 c0_hi, c0_lo,
12140 c1_hi, c1_lo,
12141 c2_hi, c2_lo,
12142 c3_hi, c3_lo,
12143 c4_hi, c4_lo);
12144
12145 c0_hi = s0_512_hi(ah, al);
12146 c0_lo = s0_512_lo(ah, al);
12147 c1_hi = maj64_hi(ah, al, bh, bl, ch);
12148 c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
12149
12150 var T2_hi = sum64_hi$1(c0_hi, c0_lo, c1_hi, c1_lo);
12151 var T2_lo = sum64_lo$1(c0_hi, c0_lo, c1_hi, c1_lo);
12152
12153 hh = gh;
12154 hl = gl;
12155
12156 gh = fh;
12157 gl = fl;
12158
12159 fh = eh;
12160 fl = el;
12161
12162 eh = sum64_hi$1(dh, dl, T1_hi, T1_lo);
12163 el = sum64_lo$1(dl, dl, T1_hi, T1_lo);
12164
12165 dh = ch;
12166 dl = cl;
12167
12168 ch = bh;
12169 cl = bl;
12170
12171 bh = ah;
12172 bl = al;
12173
12174 ah = sum64_hi$1(T1_hi, T1_lo, T2_hi, T2_lo);
12175 al = sum64_lo$1(T1_hi, T1_lo, T2_hi, T2_lo);
12176 }
12177
12178 sum64$1(this.h, 0, ah, al);
12179 sum64$1(this.h, 2, bh, bl);
12180 sum64$1(this.h, 4, ch, cl);
12181 sum64$1(this.h, 6, dh, dl);
12182 sum64$1(this.h, 8, eh, el);
12183 sum64$1(this.h, 10, fh, fl);
12184 sum64$1(this.h, 12, gh, gl);
12185 sum64$1(this.h, 14, hh, hl);
12186};
12187
12188SHA512.prototype._digest = function digest(enc) {
12189 if (enc === 'hex')
12190 return utils.toHex32(this.h, 'big');
12191 else
12192 return utils.split32(this.h, 'big');
12193};
12194
12195function ch64_hi(xh, xl, yh, yl, zh) {
12196 var r = (xh & yh) ^ ((~xh) & zh);
12197 if (r < 0)
12198 r += 0x100000000;
12199 return r;
12200}
12201
12202function ch64_lo(xh, xl, yh, yl, zh, zl) {
12203 var r = (xl & yl) ^ ((~xl) & zl);
12204 if (r < 0)
12205 r += 0x100000000;
12206 return r;
12207}
12208
12209function maj64_hi(xh, xl, yh, yl, zh) {
12210 var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
12211 if (r < 0)
12212 r += 0x100000000;
12213 return r;
12214}
12215
12216function maj64_lo(xh, xl, yh, yl, zh, zl) {
12217 var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
12218 if (r < 0)
12219 r += 0x100000000;
12220 return r;
12221}
12222
12223function s0_512_hi(xh, xl) {
12224 var c0_hi = rotr64_hi$1(xh, xl, 28);
12225 var c1_hi = rotr64_hi$1(xl, xh, 2); // 34
12226 var c2_hi = rotr64_hi$1(xl, xh, 7); // 39
12227
12228 var r = c0_hi ^ c1_hi ^ c2_hi;
12229 if (r < 0)
12230 r += 0x100000000;
12231 return r;
12232}
12233
12234function s0_512_lo(xh, xl) {
12235 var c0_lo = rotr64_lo$1(xh, xl, 28);
12236 var c1_lo = rotr64_lo$1(xl, xh, 2); // 34
12237 var c2_lo = rotr64_lo$1(xl, xh, 7); // 39
12238
12239 var r = c0_lo ^ c1_lo ^ c2_lo;
12240 if (r < 0)
12241 r += 0x100000000;
12242 return r;
12243}
12244
12245function s1_512_hi(xh, xl) {
12246 var c0_hi = rotr64_hi$1(xh, xl, 14);
12247 var c1_hi = rotr64_hi$1(xh, xl, 18);
12248 var c2_hi = rotr64_hi$1(xl, xh, 9); // 41
12249
12250 var r = c0_hi ^ c1_hi ^ c2_hi;
12251 if (r < 0)
12252 r += 0x100000000;
12253 return r;
12254}
12255
12256function s1_512_lo(xh, xl) {
12257 var c0_lo = rotr64_lo$1(xh, xl, 14);
12258 var c1_lo = rotr64_lo$1(xh, xl, 18);
12259 var c2_lo = rotr64_lo$1(xl, xh, 9); // 41
12260
12261 var r = c0_lo ^ c1_lo ^ c2_lo;
12262 if (r < 0)
12263 r += 0x100000000;
12264 return r;
12265}
12266
12267function g0_512_hi(xh, xl) {
12268 var c0_hi = rotr64_hi$1(xh, xl, 1);
12269 var c1_hi = rotr64_hi$1(xh, xl, 8);
12270 var c2_hi = shr64_hi$1(xh, xl, 7);
12271
12272 var r = c0_hi ^ c1_hi ^ c2_hi;
12273 if (r < 0)
12274 r += 0x100000000;
12275 return r;
12276}
12277
12278function g0_512_lo(xh, xl) {
12279 var c0_lo = rotr64_lo$1(xh, xl, 1);
12280 var c1_lo = rotr64_lo$1(xh, xl, 8);
12281 var c2_lo = shr64_lo$1(xh, xl, 7);
12282
12283 var r = c0_lo ^ c1_lo ^ c2_lo;
12284 if (r < 0)
12285 r += 0x100000000;
12286 return r;
12287}
12288
12289function g1_512_hi(xh, xl) {
12290 var c0_hi = rotr64_hi$1(xh, xl, 19);
12291 var c1_hi = rotr64_hi$1(xl, xh, 29); // 61
12292 var c2_hi = shr64_hi$1(xh, xl, 6);
12293
12294 var r = c0_hi ^ c1_hi ^ c2_hi;
12295 if (r < 0)
12296 r += 0x100000000;
12297 return r;
12298}
12299
12300function g1_512_lo(xh, xl) {
12301 var c0_lo = rotr64_lo$1(xh, xl, 19);
12302 var c1_lo = rotr64_lo$1(xl, xh, 29); // 61
12303 var c2_lo = shr64_lo$1(xh, xl, 6);
12304
12305 var r = c0_lo ^ c1_lo ^ c2_lo;
12306 if (r < 0)
12307 r += 0x100000000;
12308 return r;
12309}
12310
12311function SHA384() {
12312 if (!(this instanceof SHA384))
12313 return new SHA384();
12314
12315 _512.call(this);
12316 this.h = [
12317 0xcbbb9d5d, 0xc1059ed8,
12318 0x629a292a, 0x367cd507,
12319 0x9159015a, 0x3070dd17,
12320 0x152fecd8, 0xf70e5939,
12321 0x67332667, 0xffc00b31,
12322 0x8eb44a87, 0x68581511,
12323 0xdb0c2e0d, 0x64f98fa7,
12324 0x47b5481d, 0xbefa4fa4 ];
12325}
12326utils.inherits(SHA384, _512);
12327var _384 = SHA384;
12328
12329SHA384.blockSize = 1024;
12330SHA384.outSize = 384;
12331SHA384.hmacStrength = 192;
12332SHA384.padLength = 128;
12333
12334SHA384.prototype._digest = function digest(enc) {
12335 if (enc === 'hex')
12336 return utils.toHex32(this.h.slice(0, 12), 'big');
12337 else
12338 return utils.split32(this.h.slice(0, 12), 'big');
12339};
12340
12341var rotl32$1 = utils.rotl32;
12342var sum32$2 = utils.sum32;
12343var sum32_3$1 = utils.sum32_3;
12344var sum32_4$2 = utils.sum32_4;
12345var BlockHash$3 = common.BlockHash;
12346
12347function RIPEMD160() {
12348 if (!(this instanceof RIPEMD160))
12349 return new RIPEMD160();
12350
12351 BlockHash$3.call(this);
12352
12353 this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
12354 this.endian = 'little';
12355}
12356utils.inherits(RIPEMD160, BlockHash$3);
12357var ripemd160 = RIPEMD160;
12358
12359RIPEMD160.blockSize = 512;
12360RIPEMD160.outSize = 160;
12361RIPEMD160.hmacStrength = 192;
12362RIPEMD160.padLength = 64;
12363
12364RIPEMD160.prototype._update = function update(msg, start) {
12365 var A = this.h[0];
12366 var B = this.h[1];
12367 var C = this.h[2];
12368 var D = this.h[3];
12369 var E = this.h[4];
12370 var Ah = A;
12371 var Bh = B;
12372 var Ch = C;
12373 var Dh = D;
12374 var Eh = E;
12375 for (var j = 0; j < 80; j++) {
12376 var T = sum32$2(
12377 rotl32$1(
12378 sum32_4$2(A, f(j, B, C, D), msg[r[j] + start], K(j)),
12379 s[j]),
12380 E);
12381 A = E;
12382 E = D;
12383 D = rotl32$1(C, 10);
12384 C = B;
12385 B = T;
12386 T = sum32$2(
12387 rotl32$1(
12388 sum32_4$2(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
12389 sh[j]),
12390 Eh);
12391 Ah = Eh;
12392 Eh = Dh;
12393 Dh = rotl32$1(Ch, 10);
12394 Ch = Bh;
12395 Bh = T;
12396 }
12397 T = sum32_3$1(this.h[1], C, Dh);
12398 this.h[1] = sum32_3$1(this.h[2], D, Eh);
12399 this.h[2] = sum32_3$1(this.h[3], E, Ah);
12400 this.h[3] = sum32_3$1(this.h[4], A, Bh);
12401 this.h[4] = sum32_3$1(this.h[0], B, Ch);
12402 this.h[0] = T;
12403};
12404
12405RIPEMD160.prototype._digest = function digest(enc) {
12406 if (enc === 'hex')
12407 return utils.toHex32(this.h, 'little');
12408 else
12409 return utils.split32(this.h, 'little');
12410};
12411
12412function f(j, x, y, z) {
12413 if (j <= 15)
12414 return x ^ y ^ z;
12415 else if (j <= 31)
12416 return (x & y) | ((~x) & z);
12417 else if (j <= 47)
12418 return (x | (~y)) ^ z;
12419 else if (j <= 63)
12420 return (x & z) | (y & (~z));
12421 else
12422 return x ^ (y | (~z));
12423}
12424
12425function K(j) {
12426 if (j <= 15)
12427 return 0x00000000;
12428 else if (j <= 31)
12429 return 0x5a827999;
12430 else if (j <= 47)
12431 return 0x6ed9eba1;
12432 else if (j <= 63)
12433 return 0x8f1bbcdc;
12434 else
12435 return 0xa953fd4e;
12436}
12437
12438function Kh(j) {
12439 if (j <= 15)
12440 return 0x50a28be6;
12441 else if (j <= 31)
12442 return 0x5c4dd124;
12443 else if (j <= 47)
12444 return 0x6d703ef3;
12445 else if (j <= 63)
12446 return 0x7a6d76e9;
12447 else
12448 return 0x00000000;
12449}
12450
12451var r = [
12452 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
12453 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
12454 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
12455 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
12456 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
12457];
12458
12459var rh = [
12460 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
12461 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
12462 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
12463 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12464 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
12465];
12466
12467var s = [
12468 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
12469 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
12470 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
12471 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
12472 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
12473];
12474
12475var sh = [
12476 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
12477 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
12478 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
12479 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
12480 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
12481];
12482
12483var ripemd = {
12484 ripemd160: ripemd160
12485};
12486
12487/**
12488 * A fast MD5 JavaScript implementation
12489 * Copyright (c) 2012 Joseph Myers
12490 * http://www.myersdaily.org/joseph/javascript/md5-text.html
12491 *
12492 * Permission to use, copy, modify, and distribute this software
12493 * and its documentation for any purposes and without
12494 * fee is hereby granted provided that this copyright notice
12495 * appears in all copies.
12496 *
12497 * Of course, this soft is provided "as is" without express or implied
12498 * warranty of any kind.
12499 */
12500
12501// MD5 Digest
12502async function md5(entree) {
12503 const digest = md51(util.uint8ArrayToStr(entree));
12504 return util.hexToUint8Array(hex(digest));
12505}
12506
12507function md5cycle(x, k) {
12508 let a = x[0];
12509 let b = x[1];
12510 let c = x[2];
12511 let d = x[3];
12512
12513 a = ff(a, b, c, d, k[0], 7, -680876936);
12514 d = ff(d, a, b, c, k[1], 12, -389564586);
12515 c = ff(c, d, a, b, k[2], 17, 606105819);
12516 b = ff(b, c, d, a, k[3], 22, -1044525330);
12517 a = ff(a, b, c, d, k[4], 7, -176418897);
12518 d = ff(d, a, b, c, k[5], 12, 1200080426);
12519 c = ff(c, d, a, b, k[6], 17, -1473231341);
12520 b = ff(b, c, d, a, k[7], 22, -45705983);
12521 a = ff(a, b, c, d, k[8], 7, 1770035416);
12522 d = ff(d, a, b, c, k[9], 12, -1958414417);
12523 c = ff(c, d, a, b, k[10], 17, -42063);
12524 b = ff(b, c, d, a, k[11], 22, -1990404162);
12525 a = ff(a, b, c, d, k[12], 7, 1804603682);
12526 d = ff(d, a, b, c, k[13], 12, -40341101);
12527 c = ff(c, d, a, b, k[14], 17, -1502002290);
12528 b = ff(b, c, d, a, k[15], 22, 1236535329);
12529
12530 a = gg(a, b, c, d, k[1], 5, -165796510);
12531 d = gg(d, a, b, c, k[6], 9, -1069501632);
12532 c = gg(c, d, a, b, k[11], 14, 643717713);
12533 b = gg(b, c, d, a, k[0], 20, -373897302);
12534 a = gg(a, b, c, d, k[5], 5, -701558691);
12535 d = gg(d, a, b, c, k[10], 9, 38016083);
12536 c = gg(c, d, a, b, k[15], 14, -660478335);
12537 b = gg(b, c, d, a, k[4], 20, -405537848);
12538 a = gg(a, b, c, d, k[9], 5, 568446438);
12539 d = gg(d, a, b, c, k[14], 9, -1019803690);
12540 c = gg(c, d, a, b, k[3], 14, -187363961);
12541 b = gg(b, c, d, a, k[8], 20, 1163531501);
12542 a = gg(a, b, c, d, k[13], 5, -1444681467);
12543 d = gg(d, a, b, c, k[2], 9, -51403784);
12544 c = gg(c, d, a, b, k[7], 14, 1735328473);
12545 b = gg(b, c, d, a, k[12], 20, -1926607734);
12546
12547 a = hh(a, b, c, d, k[5], 4, -378558);
12548 d = hh(d, a, b, c, k[8], 11, -2022574463);
12549 c = hh(c, d, a, b, k[11], 16, 1839030562);
12550 b = hh(b, c, d, a, k[14], 23, -35309556);
12551 a = hh(a, b, c, d, k[1], 4, -1530992060);
12552 d = hh(d, a, b, c, k[4], 11, 1272893353);
12553 c = hh(c, d, a, b, k[7], 16, -155497632);
12554 b = hh(b, c, d, a, k[10], 23, -1094730640);
12555 a = hh(a, b, c, d, k[13], 4, 681279174);
12556 d = hh(d, a, b, c, k[0], 11, -358537222);
12557 c = hh(c, d, a, b, k[3], 16, -722521979);
12558 b = hh(b, c, d, a, k[6], 23, 76029189);
12559 a = hh(a, b, c, d, k[9], 4, -640364487);
12560 d = hh(d, a, b, c, k[12], 11, -421815835);
12561 c = hh(c, d, a, b, k[15], 16, 530742520);
12562 b = hh(b, c, d, a, k[2], 23, -995338651);
12563
12564 a = ii(a, b, c, d, k[0], 6, -198630844);
12565 d = ii(d, a, b, c, k[7], 10, 1126891415);
12566 c = ii(c, d, a, b, k[14], 15, -1416354905);
12567 b = ii(b, c, d, a, k[5], 21, -57434055);
12568 a = ii(a, b, c, d, k[12], 6, 1700485571);
12569 d = ii(d, a, b, c, k[3], 10, -1894986606);
12570 c = ii(c, d, a, b, k[10], 15, -1051523);
12571 b = ii(b, c, d, a, k[1], 21, -2054922799);
12572 a = ii(a, b, c, d, k[8], 6, 1873313359);
12573 d = ii(d, a, b, c, k[15], 10, -30611744);
12574 c = ii(c, d, a, b, k[6], 15, -1560198380);
12575 b = ii(b, c, d, a, k[13], 21, 1309151649);
12576 a = ii(a, b, c, d, k[4], 6, -145523070);
12577 d = ii(d, a, b, c, k[11], 10, -1120210379);
12578 c = ii(c, d, a, b, k[2], 15, 718787259);
12579 b = ii(b, c, d, a, k[9], 21, -343485551);
12580
12581 x[0] = add32(a, x[0]);
12582 x[1] = add32(b, x[1]);
12583 x[2] = add32(c, x[2]);
12584 x[3] = add32(d, x[3]);
12585}
12586
12587function cmn(q, a, b, x, s, t) {
12588 a = add32(add32(a, q), add32(x, t));
12589 return add32((a << s) | (a >>> (32 - s)), b);
12590}
12591
12592function ff(a, b, c, d, x, s, t) {
12593 return cmn((b & c) | ((~b) & d), a, b, x, s, t);
12594}
12595
12596function gg(a, b, c, d, x, s, t) {
12597 return cmn((b & d) | (c & (~d)), a, b, x, s, t);
12598}
12599
12600function hh(a, b, c, d, x, s, t) {
12601 return cmn(b ^ c ^ d, a, b, x, s, t);
12602}
12603
12604function ii(a, b, c, d, x, s, t) {
12605 return cmn(c ^ (b | (~d)), a, b, x, s, t);
12606}
12607
12608function md51(s) {
12609 const n = s.length;
12610 const state = [1732584193, -271733879, -1732584194, 271733878];
12611 let i;
12612 for (i = 64; i <= s.length; i += 64) {
12613 md5cycle(state, md5blk(s.substring(i - 64, i)));
12614 }
12615 s = s.substring(i - 64);
12616 const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
12617 for (i = 0; i < s.length; i++) {
12618 tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
12619 }
12620 tail[i >> 2] |= 0x80 << ((i % 4) << 3);
12621 if (i > 55) {
12622 md5cycle(state, tail);
12623 for (i = 0; i < 16; i++) {
12624 tail[i] = 0;
12625 }
12626 }
12627 tail[14] = n * 8;
12628 md5cycle(state, tail);
12629 return state;
12630}
12631
12632/* there needs to be support for Unicode here,
12633 * unless we pretend that we can redefine the MD-5
12634 * algorithm for multi-byte characters (perhaps
12635 * by adding every four 16-bit characters and
12636 * shortening the sum to 32 bits). Otherwise
12637 * I suggest performing MD-5 as if every character
12638 * was two bytes--e.g., 0040 0025 = @%--but then
12639 * how will an ordinary MD-5 sum be matched?
12640 * There is no way to standardize text to something
12641 * like UTF-8 before transformation; speed cost is
12642 * utterly prohibitive. The JavaScript standard
12643 * itself needs to look at this: it should start
12644 * providing access to strings as preformed UTF-8
12645 * 8-bit unsigned value arrays.
12646 */
12647function md5blk(s) { /* I figured global was faster. */
12648 const md5blks = [];
12649 let i; /* Andy King said do it this way. */
12650 for (i = 0; i < 64; i += 4) {
12651 md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) <<
12652 24);
12653 }
12654 return md5blks;
12655}
12656
12657const hex_chr = '0123456789abcdef'.split('');
12658
12659function rhex(n) {
12660 let s = '';
12661 let j = 0;
12662 for (; j < 4; j++) {
12663 s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
12664 }
12665 return s;
12666}
12667
12668function hex(x) {
12669 for (let i = 0; i < x.length; i++) {
12670 x[i] = rhex(x[i]);
12671 }
12672 return x.join('');
12673}
12674
12675/* this function is much faster,
12676so if possible we use it. Some IEs
12677are the only ones I know of that
12678need the idiotic second function,
12679generated by an if clause. */
12680
12681function add32(a, b) {
12682 return (a + b) & 0xFFFFFFFF;
12683}
12684
12685/**
12686 * @fileoverview Provides an interface to hashing functions available in Node.js or external libraries.
12687 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
12688 * @see {@link https://github.com/indutny/hash.js|hash.js}
12689 * @module crypto/hash
12690 * @private
12691 */
12692
12693const webCrypto = util.getWebCrypto();
12694const nodeCrypto = util.getNodeCrypto();
12695const Buffer$1 = util.getNodeBuffer();
12696
12697function node_hash(type) {
12698 return async function (data) {
12699 const shasum = nodeCrypto.createHash(type);
12700 return stream.transform(data, value => {
12701 shasum.update(Buffer$1.from(value));
12702 }, () => new Uint8Array(shasum.digest()));
12703 };
12704}
12705
12706function hashjs_hash(hash, webCryptoHash) {
12707 return async function(data, config = defaultConfig) {
12708 if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) {
12709 return new Uint8Array(await webCrypto.digest(webCryptoHash, data));
12710 }
12711 const hashInstance = hash();
12712 return stream.transform(data, value => {
12713 hashInstance.update(value);
12714 }, () => new Uint8Array(hashInstance.digest()));
12715 };
12716}
12717
12718function asmcrypto_hash(hash, webCryptoHash) {
12719 return async function(data, config = defaultConfig) {
12720 if (util.isStream(data)) {
12721 const hashInstance = new hash();
12722 return stream.transform(data, value => {
12723 hashInstance.process(value);
12724 }, () => hashInstance.finish().result);
12725 } else if (webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) {
12726 return new Uint8Array(await webCrypto.digest(webCryptoHash, data));
12727 } else {
12728 return hash.bytes(data);
12729 }
12730 };
12731}
12732
12733let hash_fns;
12734if (nodeCrypto) { // Use Node native crypto for all hash functions
12735 hash_fns = {
12736 md5: node_hash('md5'),
12737 sha1: node_hash('sha1'),
12738 sha224: node_hash('sha224'),
12739 sha256: node_hash('sha256'),
12740 sha384: node_hash('sha384'),
12741 sha512: node_hash('sha512'),
12742 ripemd: node_hash('ripemd160')
12743 };
12744} else { // Use JS fallbacks
12745 hash_fns = {
12746 md5: md5,
12747 sha1: asmcrypto_hash(Sha1, navigator.userAgent.indexOf('Edge') === -1 && 'SHA-1'),
12748 sha224: hashjs_hash(_224),
12749 sha256: asmcrypto_hash(Sha256, 'SHA-256'),
12750 sha384: hashjs_hash(_384, 'SHA-384'),
12751 sha512: hashjs_hash(_512, 'SHA-512'), // asmcrypto sha512 is huge.
12752 ripemd: hashjs_hash(ripemd160)
12753 };
12754}
12755
12756var hash = {
12757
12758 /** @see module:md5 */
12759 md5: hash_fns.md5,
12760 /** @see asmCrypto */
12761 sha1: hash_fns.sha1,
12762 /** @see hash.js */
12763 sha224: hash_fns.sha224,
12764 /** @see asmCrypto */
12765 sha256: hash_fns.sha256,
12766 /** @see hash.js */
12767 sha384: hash_fns.sha384,
12768 /** @see asmCrypto */
12769 sha512: hash_fns.sha512,
12770 /** @see hash.js */
12771 ripemd: hash_fns.ripemd,
12772
12773 /**
12774 * Create a hash on the specified data using the specified algorithm
12775 * @param {module:enums.hash} algo - Hash algorithm type (see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
12776 * @param {Uint8Array} data - Data to be hashed
12777 * @returns {Uint8Array} Hash value.
12778 * @async
12779 */
12780 digest: function(algo, data) {
12781 switch (algo) {
12782 case 1:
12783 // - MD5 [HAC]
12784 return this.md5(data);
12785 case 2:
12786 // - SHA-1 [FIPS180]
12787 return this.sha1(data);
12788 case 3:
12789 // - RIPE-MD/160 [HAC]
12790 return this.ripemd(data);
12791 case 8:
12792 // - SHA256 [FIPS180]
12793 return this.sha256(data);
12794 case 9:
12795 // - SHA384 [FIPS180]
12796 return this.sha384(data);
12797 case 10:
12798 // - SHA512 [FIPS180]
12799 return this.sha512(data);
12800 case 11:
12801 // - SHA224 [FIPS180]
12802 return this.sha224(data);
12803 default:
12804 throw new Error('Invalid hash function.');
12805 }
12806 },
12807
12808 /**
12809 * Returns the hash size in bytes of the specified hash algorithm type
12810 * @param {module:enums.hash} algo - Hash algorithm type (See {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
12811 * @returns {Integer} Size in bytes of the resulting hash.
12812 */
12813 getHashByteLength: function(algo) {
12814 switch (algo) {
12815 case 1: // - MD5 [HAC]
12816 return 16;
12817 case 2: // - SHA-1 [FIPS180]
12818 case 3: // - RIPE-MD/160 [HAC]
12819 return 20;
12820 case 8: // - SHA256 [FIPS180]
12821 return 32;
12822 case 9: // - SHA384 [FIPS180]
12823 return 48;
12824 case 10: // - SHA512 [FIPS180]
12825 return 64;
12826 case 11: // - SHA224 [FIPS180]
12827 return 28;
12828 default:
12829 throw new Error('Invalid hash algorithm.');
12830 }
12831 }
12832};
12833
12834class AES_CFB {
12835 static encrypt(data, key, iv) {
12836 return new AES_CFB(key, iv).encrypt(data);
12837 }
12838 static decrypt(data, key, iv) {
12839 return new AES_CFB(key, iv).decrypt(data);
12840 }
12841 constructor(key, iv, aes) {
12842 this.aes = aes ? aes : new AES(key, iv, true, 'CFB');
12843 delete this.aes.padding;
12844 }
12845 encrypt(data) {
12846 const r1 = this.aes.AES_Encrypt_process(data);
12847 const r2 = this.aes.AES_Encrypt_finish();
12848 return joinBytes(r1, r2);
12849 }
12850 decrypt(data) {
12851 const r1 = this.aes.AES_Decrypt_process(data);
12852 const r2 = this.aes.AES_Decrypt_finish();
12853 return joinBytes(r1, r2);
12854 }
12855}
12856
12857// Modified by ProtonTech AG
12858
12859const webCrypto$1 = util.getWebCrypto();
12860const nodeCrypto$1 = util.getNodeCrypto();
12861const Buffer$2 = util.getNodeBuffer();
12862
12863const knownAlgos = nodeCrypto$1 ? nodeCrypto$1.getCiphers() : [];
12864const nodeAlgos = {
12865 idea: knownAlgos.includes('idea-cfb') ? 'idea-cfb' : undefined, /* Unused, not implemented */
12866 tripledes: knownAlgos.includes('des-ede3-cfb') ? 'des-ede3-cfb' : undefined,
12867 cast5: knownAlgos.includes('cast5-cfb') ? 'cast5-cfb' : undefined,
12868 blowfish: knownAlgos.includes('bf-cfb') ? 'bf-cfb' : undefined,
12869 aes128: knownAlgos.includes('aes-128-cfb') ? 'aes-128-cfb' : undefined,
12870 aes192: knownAlgos.includes('aes-192-cfb') ? 'aes-192-cfb' : undefined,
12871 aes256: knownAlgos.includes('aes-256-cfb') ? 'aes-256-cfb' : undefined
12872 /* twofish is not implemented in OpenSSL */
12873};
12874
12875async function encrypt(algo, key, plaintext, iv, config) {
12876 if (util.getNodeCrypto() && nodeAlgos[algo]) { // Node crypto library.
12877 return nodeEncrypt(algo, key, plaintext, iv);
12878 }
12879 if (algo.substr(0, 3) === 'aes') {
12880 return aesEncrypt(algo, key, plaintext, iv, config);
12881 }
12882
12883 const cipherfn = new cipher[algo](key);
12884 const block_size = cipherfn.blockSize;
12885
12886 const blockc = iv.slice();
12887 let pt = new Uint8Array();
12888 const process = chunk => {
12889 if (chunk) {
12890 pt = util.concatUint8Array([pt, chunk]);
12891 }
12892 const ciphertext = new Uint8Array(pt.length);
12893 let i;
12894 let j = 0;
12895 while (chunk ? pt.length >= block_size : pt.length) {
12896 const encblock = cipherfn.encrypt(blockc);
12897 for (i = 0; i < block_size; i++) {
12898 blockc[i] = pt[i] ^ encblock[i];
12899 ciphertext[j++] = blockc[i];
12900 }
12901 pt = pt.subarray(block_size);
12902 }
12903 return ciphertext.subarray(0, j);
12904 };
12905 return stream.transform(plaintext, process, process);
12906}
12907
12908async function decrypt(algo, key, ciphertext, iv) {
12909 if (util.getNodeCrypto() && nodeAlgos[algo]) { // Node crypto library.
12910 return nodeDecrypt(algo, key, ciphertext, iv);
12911 }
12912 if (algo.substr(0, 3) === 'aes') {
12913 return aesDecrypt(algo, key, ciphertext, iv);
12914 }
12915
12916 const cipherfn = new cipher[algo](key);
12917 const block_size = cipherfn.blockSize;
12918
12919 let blockp = iv;
12920 let ct = new Uint8Array();
12921 const process = chunk => {
12922 if (chunk) {
12923 ct = util.concatUint8Array([ct, chunk]);
12924 }
12925 const plaintext = new Uint8Array(ct.length);
12926 let i;
12927 let j = 0;
12928 while (chunk ? ct.length >= block_size : ct.length) {
12929 const decblock = cipherfn.encrypt(blockp);
12930 blockp = ct;
12931 for (i = 0; i < block_size; i++) {
12932 plaintext[j++] = blockp[i] ^ decblock[i];
12933 }
12934 ct = ct.subarray(block_size);
12935 }
12936 return plaintext.subarray(0, j);
12937 };
12938 return stream.transform(ciphertext, process, process);
12939}
12940
12941function aesEncrypt(algo, key, pt, iv, config) {
12942 if (
12943 util.getWebCrypto() &&
12944 key.length !== 24 && // Chrome doesn't support 192 bit keys, see https://www.chromium.org/blink/webcrypto#TOC-AES-support
12945 !util.isStream(pt) &&
12946 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
12947 ) { // Web Crypto
12948 return webEncrypt(algo, key, pt, iv);
12949 }
12950 // asm.js fallback
12951 const cfb = new AES_CFB(key, iv);
12952 return stream.transform(pt, value => cfb.aes.AES_Encrypt_process(value), () => cfb.aes.AES_Encrypt_finish());
12953}
12954
12955function aesDecrypt(algo, key, ct, iv) {
12956 if (util.isStream(ct)) {
12957 const cfb = new AES_CFB(key, iv);
12958 return stream.transform(ct, value => cfb.aes.AES_Decrypt_process(value), () => cfb.aes.AES_Decrypt_finish());
12959 }
12960 return AES_CFB.decrypt(ct, key, iv);
12961}
12962
12963function xorMut(a, b) {
12964 for (let i = 0; i < a.length; i++) {
12965 a[i] = a[i] ^ b[i];
12966 }
12967}
12968
12969async function webEncrypt(algo, key, pt, iv) {
12970 const ALGO = 'AES-CBC';
12971 const _key = await webCrypto$1.importKey('raw', key, { name: ALGO }, false, ['encrypt']);
12972 const { blockSize } = cipher[algo];
12973 const cbc_pt = util.concatUint8Array([new Uint8Array(blockSize), pt]);
12974 const ct = new Uint8Array(await webCrypto$1.encrypt({ name: ALGO, iv }, _key, cbc_pt)).subarray(0, pt.length);
12975 xorMut(ct, pt);
12976 return ct;
12977}
12978
12979function nodeEncrypt(algo, key, pt, iv) {
12980 key = Buffer$2.from(key);
12981 iv = Buffer$2.from(iv);
12982 const cipherObj = new nodeCrypto$1.createCipheriv(nodeAlgos[algo], key, iv);
12983 return stream.transform(pt, value => new Uint8Array(cipherObj.update(Buffer$2.from(value))));
12984}
12985
12986function nodeDecrypt(algo, key, ct, iv) {
12987 key = Buffer$2.from(key);
12988 iv = Buffer$2.from(iv);
12989 const decipherObj = new nodeCrypto$1.createDecipheriv(nodeAlgos[algo], key, iv);
12990 return stream.transform(ct, value => new Uint8Array(decipherObj.update(Buffer$2.from(value))));
12991}
12992
12993var cfb = /*#__PURE__*/Object.freeze({
12994 __proto__: null,
12995 encrypt: encrypt,
12996 decrypt: decrypt
12997});
12998
12999const _AES_GCM_data_maxLength = 68719476704; // 2^36 - 2^5
13000class AES_GCM {
13001 constructor(key, nonce, adata, tagSize = 16, aes) {
13002 this.tagSize = tagSize;
13003 this.gamma0 = 0;
13004 this.counter = 1;
13005 this.aes = aes ? aes : new AES(key, undefined, false, 'CTR');
13006 let { asm, heap } = this.aes.acquire_asm();
13007 // Init GCM
13008 asm.gcm_init();
13009 // Tag size
13010 if (this.tagSize < 4 || this.tagSize > 16)
13011 throw new IllegalArgumentError('illegal tagSize value');
13012 // Nonce
13013 const noncelen = nonce.length || 0;
13014 const noncebuf = new Uint8Array(16);
13015 if (noncelen !== 12) {
13016 this._gcm_mac_process(nonce);
13017 heap[0] = 0;
13018 heap[1] = 0;
13019 heap[2] = 0;
13020 heap[3] = 0;
13021 heap[4] = 0;
13022 heap[5] = 0;
13023 heap[6] = 0;
13024 heap[7] = 0;
13025 heap[8] = 0;
13026 heap[9] = 0;
13027 heap[10] = 0;
13028 heap[11] = noncelen >>> 29;
13029 heap[12] = (noncelen >>> 21) & 255;
13030 heap[13] = (noncelen >>> 13) & 255;
13031 heap[14] = (noncelen >>> 5) & 255;
13032 heap[15] = (noncelen << 3) & 255;
13033 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
13034 asm.get_iv(AES_asm.HEAP_DATA);
13035 asm.set_iv(0, 0, 0, 0);
13036 noncebuf.set(heap.subarray(0, 16));
13037 }
13038 else {
13039 noncebuf.set(nonce);
13040 noncebuf[15] = 1;
13041 }
13042 const nonceview = new DataView(noncebuf.buffer);
13043 this.gamma0 = nonceview.getUint32(12);
13044 asm.set_nonce(nonceview.getUint32(0), nonceview.getUint32(4), nonceview.getUint32(8), 0);
13045 asm.set_mask(0, 0, 0, 0xffffffff);
13046 // Associated data
13047 if (adata !== undefined) {
13048 if (adata.length > _AES_GCM_data_maxLength)
13049 throw new IllegalArgumentError('illegal adata length');
13050 if (adata.length) {
13051 this.adata = adata;
13052 this._gcm_mac_process(adata);
13053 }
13054 else {
13055 this.adata = undefined;
13056 }
13057 }
13058 else {
13059 this.adata = undefined;
13060 }
13061 // Counter
13062 if (this.counter < 1 || this.counter > 0xffffffff)
13063 throw new RangeError('counter must be a positive 32-bit integer');
13064 asm.set_counter(0, 0, 0, (this.gamma0 + this.counter) | 0);
13065 }
13066 static encrypt(cleartext, key, nonce, adata, tagsize) {
13067 return new AES_GCM(key, nonce, adata, tagsize).encrypt(cleartext);
13068 }
13069 static decrypt(ciphertext, key, nonce, adata, tagsize) {
13070 return new AES_GCM(key, nonce, adata, tagsize).decrypt(ciphertext);
13071 }
13072 encrypt(data) {
13073 return this.AES_GCM_encrypt(data);
13074 }
13075 decrypt(data) {
13076 return this.AES_GCM_decrypt(data);
13077 }
13078 AES_GCM_Encrypt_process(data) {
13079 let dpos = 0;
13080 let dlen = data.length || 0;
13081 let { asm, heap } = this.aes.acquire_asm();
13082 let counter = this.counter;
13083 let pos = this.aes.pos;
13084 let len = this.aes.len;
13085 let rpos = 0;
13086 let rlen = (len + dlen) & -16;
13087 let wlen = 0;
13088 if (((counter - 1) << 4) + len + dlen > _AES_GCM_data_maxLength)
13089 throw new RangeError('counter overflow');
13090 const result = new Uint8Array(rlen);
13091 while (dlen > 0) {
13092 wlen = _heap_write(heap, pos + len, data, dpos, dlen);
13093 len += wlen;
13094 dpos += wlen;
13095 dlen -= wlen;
13096 wlen = asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, len);
13097 wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
13098 if (wlen)
13099 result.set(heap.subarray(pos, pos + wlen), rpos);
13100 counter += wlen >>> 4;
13101 rpos += wlen;
13102 if (wlen < len) {
13103 pos += wlen;
13104 len -= wlen;
13105 }
13106 else {
13107 pos = 0;
13108 len = 0;
13109 }
13110 }
13111 this.counter = counter;
13112 this.aes.pos = pos;
13113 this.aes.len = len;
13114 return result;
13115 }
13116 AES_GCM_Encrypt_finish() {
13117 let { asm, heap } = this.aes.acquire_asm();
13118 let counter = this.counter;
13119 let tagSize = this.tagSize;
13120 let adata = this.adata;
13121 let pos = this.aes.pos;
13122 let len = this.aes.len;
13123 const result = new Uint8Array(len + tagSize);
13124 asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, (len + 15) & -16);
13125 if (len)
13126 result.set(heap.subarray(pos, pos + len));
13127 let i = len;
13128 for (; i & 15; i++)
13129 heap[pos + i] = 0;
13130 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
13131 const alen = adata !== undefined ? adata.length : 0;
13132 const clen = ((counter - 1) << 4) + len;
13133 heap[0] = 0;
13134 heap[1] = 0;
13135 heap[2] = 0;
13136 heap[3] = alen >>> 29;
13137 heap[4] = alen >>> 21;
13138 heap[5] = (alen >>> 13) & 255;
13139 heap[6] = (alen >>> 5) & 255;
13140 heap[7] = (alen << 3) & 255;
13141 heap[8] = heap[9] = heap[10] = 0;
13142 heap[11] = clen >>> 29;
13143 heap[12] = (clen >>> 21) & 255;
13144 heap[13] = (clen >>> 13) & 255;
13145 heap[14] = (clen >>> 5) & 255;
13146 heap[15] = (clen << 3) & 255;
13147 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
13148 asm.get_iv(AES_asm.HEAP_DATA);
13149 asm.set_counter(0, 0, 0, this.gamma0);
13150 asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
13151 result.set(heap.subarray(0, tagSize), len);
13152 this.counter = 1;
13153 this.aes.pos = 0;
13154 this.aes.len = 0;
13155 return result;
13156 }
13157 AES_GCM_Decrypt_process(data) {
13158 let dpos = 0;
13159 let dlen = data.length || 0;
13160 let { asm, heap } = this.aes.acquire_asm();
13161 let counter = this.counter;
13162 let tagSize = this.tagSize;
13163 let pos = this.aes.pos;
13164 let len = this.aes.len;
13165 let rpos = 0;
13166 let rlen = len + dlen > tagSize ? (len + dlen - tagSize) & -16 : 0;
13167 let tlen = len + dlen - rlen;
13168 let wlen = 0;
13169 if (((counter - 1) << 4) + len + dlen > _AES_GCM_data_maxLength)
13170 throw new RangeError('counter overflow');
13171 const result = new Uint8Array(rlen);
13172 while (dlen > tlen) {
13173 wlen = _heap_write(heap, pos + len, data, dpos, dlen - tlen);
13174 len += wlen;
13175 dpos += wlen;
13176 dlen -= wlen;
13177 wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
13178 wlen = asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, wlen);
13179 if (wlen)
13180 result.set(heap.subarray(pos, pos + wlen), rpos);
13181 counter += wlen >>> 4;
13182 rpos += wlen;
13183 pos = 0;
13184 len = 0;
13185 }
13186 if (dlen > 0) {
13187 len += _heap_write(heap, 0, data, dpos, dlen);
13188 }
13189 this.counter = counter;
13190 this.aes.pos = pos;
13191 this.aes.len = len;
13192 return result;
13193 }
13194 AES_GCM_Decrypt_finish() {
13195 let { asm, heap } = this.aes.acquire_asm();
13196 let tagSize = this.tagSize;
13197 let adata = this.adata;
13198 let counter = this.counter;
13199 let pos = this.aes.pos;
13200 let len = this.aes.len;
13201 let rlen = len - tagSize;
13202 if (len < tagSize)
13203 throw new IllegalStateError('authentication tag not found');
13204 const result = new Uint8Array(rlen);
13205 const atag = new Uint8Array(heap.subarray(pos + rlen, pos + len));
13206 let i = rlen;
13207 for (; i & 15; i++)
13208 heap[pos + i] = 0;
13209 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
13210 asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, i);
13211 if (rlen)
13212 result.set(heap.subarray(pos, pos + rlen));
13213 const alen = adata !== undefined ? adata.length : 0;
13214 const clen = ((counter - 1) << 4) + len - tagSize;
13215 heap[0] = 0;
13216 heap[1] = 0;
13217 heap[2] = 0;
13218 heap[3] = alen >>> 29;
13219 heap[4] = alen >>> 21;
13220 heap[5] = (alen >>> 13) & 255;
13221 heap[6] = (alen >>> 5) & 255;
13222 heap[7] = (alen << 3) & 255;
13223 heap[8] = heap[9] = heap[10] = 0;
13224 heap[11] = clen >>> 29;
13225 heap[12] = (clen >>> 21) & 255;
13226 heap[13] = (clen >>> 13) & 255;
13227 heap[14] = (clen >>> 5) & 255;
13228 heap[15] = (clen << 3) & 255;
13229 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
13230 asm.get_iv(AES_asm.HEAP_DATA);
13231 asm.set_counter(0, 0, 0, this.gamma0);
13232 asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
13233 let acheck = 0;
13234 for (let i = 0; i < tagSize; ++i)
13235 acheck |= atag[i] ^ heap[i];
13236 if (acheck)
13237 throw new SecurityError('data integrity check failed');
13238 this.counter = 1;
13239 this.aes.pos = 0;
13240 this.aes.len = 0;
13241 return result;
13242 }
13243 AES_GCM_decrypt(data) {
13244 const result1 = this.AES_GCM_Decrypt_process(data);
13245 const result2 = this.AES_GCM_Decrypt_finish();
13246 const result = new Uint8Array(result1.length + result2.length);
13247 if (result1.length)
13248 result.set(result1);
13249 if (result2.length)
13250 result.set(result2, result1.length);
13251 return result;
13252 }
13253 AES_GCM_encrypt(data) {
13254 const result1 = this.AES_GCM_Encrypt_process(data);
13255 const result2 = this.AES_GCM_Encrypt_finish();
13256 const result = new Uint8Array(result1.length + result2.length);
13257 if (result1.length)
13258 result.set(result1);
13259 if (result2.length)
13260 result.set(result2, result1.length);
13261 return result;
13262 }
13263 _gcm_mac_process(data) {
13264 let { asm, heap } = this.aes.acquire_asm();
13265 let dpos = 0;
13266 let dlen = data.length || 0;
13267 let wlen = 0;
13268 while (dlen > 0) {
13269 wlen = _heap_write(heap, 0, data, dpos, dlen);
13270 dpos += wlen;
13271 dlen -= wlen;
13272 while (wlen & 15)
13273 heap[wlen++] = 0;
13274 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, wlen);
13275 }
13276 }
13277}
13278
13279// OpenPGP.js - An OpenPGP implementation in javascript
13280
13281const webCrypto$2 = util.getWebCrypto(); // no GCM support in IE11, Safari 9
13282const nodeCrypto$2 = util.getNodeCrypto();
13283const Buffer$3 = util.getNodeBuffer();
13284
13285const blockLength = 16;
13286const ivLength = 12; // size of the IV in bytes
13287const tagLength = 16; // size of the tag in bytes
13288const ALGO = 'AES-GCM';
13289
13290/**
13291 * Class to en/decrypt using GCM mode.
13292 * @param {String} cipher - The symmetric cipher algorithm to use e.g. 'aes128'
13293 * @param {Uint8Array} key - The encryption key
13294 */
13295async function GCM(cipher, key) {
13296 if (cipher.substr(0, 3) !== 'aes') {
13297 throw new Error('GCM mode supports only AES cipher');
13298 }
13299
13300 if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
13301 const _key = await webCrypto$2.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
13302
13303 return {
13304 encrypt: async function(pt, iv, adata = new Uint8Array()) {
13305 if (
13306 !pt.length ||
13307 // iOS does not support GCM-en/decrypting empty messages
13308 // Also, synchronous en/decryption might be faster in this case.
13309 (!adata.length && navigator.userAgent.indexOf('Edge') !== -1)
13310 // Edge does not support GCM-en/decrypting without ADATA
13311 ) {
13312 return AES_GCM.encrypt(pt, key, iv, adata);
13313 }
13314 const ct = await webCrypto$2.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, pt);
13315 return new Uint8Array(ct);
13316 },
13317
13318 decrypt: async function(ct, iv, adata = new Uint8Array()) {
13319 if (
13320 ct.length === tagLength ||
13321 // iOS does not support GCM-en/decrypting empty messages
13322 // Also, synchronous en/decryption might be faster in this case.
13323 (!adata.length && navigator.userAgent.indexOf('Edge') !== -1)
13324 // Edge does not support GCM-en/decrypting without ADATA
13325 ) {
13326 return AES_GCM.decrypt(ct, key, iv, adata);
13327 }
13328 const pt = await webCrypto$2.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength * 8 }, _key, ct);
13329 return new Uint8Array(pt);
13330 }
13331 };
13332 }
13333
13334 if (util.getNodeCrypto()) { // Node crypto library
13335 key = Buffer$3.from(key);
13336
13337 return {
13338 encrypt: async function(pt, iv, adata = new Uint8Array()) {
13339 pt = Buffer$3.from(pt);
13340 iv = Buffer$3.from(iv);
13341 adata = Buffer$3.from(adata);
13342 const en = new nodeCrypto$2.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
13343 en.setAAD(adata);
13344 const ct = Buffer$3.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
13345 return new Uint8Array(ct);
13346 },
13347
13348 decrypt: async function(ct, iv, adata = new Uint8Array()) {
13349 ct = Buffer$3.from(ct);
13350 iv = Buffer$3.from(iv);
13351 adata = Buffer$3.from(adata);
13352 const de = new nodeCrypto$2.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
13353 de.setAAD(adata);
13354 de.setAuthTag(ct.slice(ct.length - tagLength, ct.length)); // read auth tag at end of ciphertext
13355 const pt = Buffer$3.concat([de.update(ct.slice(0, ct.length - tagLength)), de.final()]);
13356 return new Uint8Array(pt);
13357 }
13358 };
13359 }
13360
13361 return {
13362 encrypt: async function(pt, iv, adata) {
13363 return AES_GCM.encrypt(pt, key, iv, adata);
13364 },
13365
13366 decrypt: async function(ct, iv, adata) {
13367 return AES_GCM.decrypt(ct, key, iv, adata);
13368 }
13369 };
13370}
13371
13372
13373/**
13374 * Get GCM nonce. Note: this operation is not defined by the standard.
13375 * A future version of the standard may define GCM mode differently,
13376 * hopefully under a different ID (we use Private/Experimental algorithm
13377 * ID 100) so that we can maintain backwards compatibility.
13378 * @param {Uint8Array} iv - The initialization vector (12 bytes)
13379 * @param {Uint8Array} chunkIndex - The chunk index (8 bytes)
13380 */
13381GCM.getNonce = function(iv, chunkIndex) {
13382 const nonce = iv.slice();
13383 for (let i = 0; i < chunkIndex.length; i++) {
13384 nonce[4 + i] ^= chunkIndex[i];
13385 }
13386 return nonce;
13387};
13388
13389GCM.blockLength = blockLength;
13390GCM.ivLength = ivLength;
13391GCM.tagLength = tagLength;
13392
13393class AES_CTR {
13394 static encrypt(data, key, nonce) {
13395 return new AES_CTR(key, nonce).encrypt(data);
13396 }
13397 static decrypt(data, key, nonce) {
13398 return new AES_CTR(key, nonce).encrypt(data);
13399 }
13400 constructor(key, nonce, aes) {
13401 this.aes = aes ? aes : new AES(key, undefined, false, 'CTR');
13402 delete this.aes.padding;
13403 this.AES_CTR_set_options(nonce);
13404 }
13405 encrypt(data) {
13406 const r1 = this.aes.AES_Encrypt_process(data);
13407 const r2 = this.aes.AES_Encrypt_finish();
13408 return joinBytes(r1, r2);
13409 }
13410 decrypt(data) {
13411 const r1 = this.aes.AES_Encrypt_process(data);
13412 const r2 = this.aes.AES_Encrypt_finish();
13413 return joinBytes(r1, r2);
13414 }
13415 AES_CTR_set_options(nonce, counter, size) {
13416 let { asm } = this.aes.acquire_asm();
13417 if (size !== undefined) {
13418 if (size < 8 || size > 48)
13419 throw new IllegalArgumentError('illegal counter size');
13420 let mask = Math.pow(2, size) - 1;
13421 asm.set_mask(0, 0, (mask / 0x100000000) | 0, mask | 0);
13422 }
13423 else {
13424 size = 48;
13425 asm.set_mask(0, 0, 0xffff, 0xffffffff);
13426 }
13427 if (nonce !== undefined) {
13428 let len = nonce.length;
13429 if (!len || len > 16)
13430 throw new IllegalArgumentError('illegal nonce size');
13431 let view = new DataView(new ArrayBuffer(16));
13432 new Uint8Array(view.buffer).set(nonce);
13433 asm.set_nonce(view.getUint32(0), view.getUint32(4), view.getUint32(8), view.getUint32(12));
13434 }
13435 else {
13436 throw new Error('nonce is required');
13437 }
13438 if (counter !== undefined) {
13439 if (counter < 0 || counter >= Math.pow(2, size))
13440 throw new IllegalArgumentError('illegal counter value');
13441 asm.set_counter(0, 0, (counter / 0x100000000) | 0, counter | 0);
13442 }
13443 }
13444}
13445
13446class AES_CBC {
13447 static encrypt(data, key, padding = true, iv) {
13448 return new AES_CBC(key, iv, padding).encrypt(data);
13449 }
13450 static decrypt(data, key, padding = true, iv) {
13451 return new AES_CBC(key, iv, padding).decrypt(data);
13452 }
13453 constructor(key, iv, padding = true, aes) {
13454 this.aes = aes ? aes : new AES(key, iv, padding, 'CBC');
13455 }
13456 encrypt(data) {
13457 const r1 = this.aes.AES_Encrypt_process(data);
13458 const r2 = this.aes.AES_Encrypt_finish();
13459 return joinBytes(r1, r2);
13460 }
13461 decrypt(data) {
13462 const r1 = this.aes.AES_Decrypt_process(data);
13463 const r2 = this.aes.AES_Decrypt_finish();
13464 return joinBytes(r1, r2);
13465 }
13466}
13467
13468/**
13469 * @fileoverview This module implements AES-CMAC on top of
13470 * native AES-CBC using either the WebCrypto API or Node.js' crypto API.
13471 * @module crypto/cmac
13472 * @private
13473 */
13474
13475const webCrypto$3 = util.getWebCrypto();
13476const nodeCrypto$3 = util.getNodeCrypto();
13477const Buffer$4 = util.getNodeBuffer();
13478
13479
13480/**
13481 * This implementation of CMAC is based on the description of OMAC in
13482 * http://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf. As per that
13483 * document:
13484 *
13485 * We have made a small modification to the OMAC algorithm as it was
13486 * originally presented, changing one of its two constants.
13487 * Specifically, the constant 4 at line 85 was the constant 1/2 (the
13488 * multiplicative inverse of 2) in the original definition of OMAC [14].
13489 * The OMAC authors indicate that they will promulgate this modification
13490 * [15], which slightly simplifies implementations.
13491 */
13492
13493const blockLength$1 = 16;
13494
13495
13496/**
13497 * xor `padding` into the end of `data`. This function implements "the
13498 * operation xor→ [which] xors the shorter string into the end of longer
13499 * one". Since data is always as least as long as padding, we can
13500 * simplify the implementation.
13501 * @param {Uint8Array} data
13502 * @param {Uint8Array} padding
13503 */
13504function rightXorMut(data, padding) {
13505 const offset = data.length - blockLength$1;
13506 for (let i = 0; i < blockLength$1; i++) {
13507 data[i + offset] ^= padding[i];
13508 }
13509 return data;
13510}
13511
13512function pad(data, padding, padding2) {
13513 // if |M| in {n, 2n, 3n, ...}
13514 if (data.length && data.length % blockLength$1 === 0) {
13515 // then return M xor→ B,
13516 return rightXorMut(data, padding);
13517 }
13518 // else return (M || 10^(n−1−(|M| mod n))) xor→ P
13519 const padded = new Uint8Array(data.length + (blockLength$1 - data.length % blockLength$1));
13520 padded.set(data);
13521 padded[data.length] = 0b10000000;
13522 return rightXorMut(padded, padding2);
13523}
13524
13525const zeroBlock = new Uint8Array(blockLength$1);
13526
13527async function CMAC(key) {
13528 const cbc = await CBC(key);
13529
13530 // L ← E_K(0^n); B ← 2L; P ← 4L
13531 const padding = util.double(await cbc(zeroBlock));
13532 const padding2 = util.double(padding);
13533
13534 return async function(data) {
13535 // return CBC_K(pad(M; B, P))
13536 return (await cbc(pad(data, padding, padding2))).subarray(-blockLength$1);
13537 };
13538}
13539
13540async function CBC(key) {
13541 if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
13542 key = await webCrypto$3.importKey('raw', key, { name: 'AES-CBC', length: key.length * 8 }, false, ['encrypt']);
13543 return async function(pt) {
13544 const ct = await webCrypto$3.encrypt({ name: 'AES-CBC', iv: zeroBlock, length: blockLength$1 * 8 }, key, pt);
13545 return new Uint8Array(ct).subarray(0, ct.byteLength - blockLength$1);
13546 };
13547 }
13548 if (util.getNodeCrypto()) { // Node crypto library
13549 key = Buffer$4.from(key);
13550 return async function(pt) {
13551 pt = Buffer$4.from(pt);
13552 const en = new nodeCrypto$3.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock);
13553 const ct = en.update(pt);
13554 return new Uint8Array(ct);
13555 };
13556 }
13557 // asm.js fallback
13558 return async function(pt) {
13559 return AES_CBC.encrypt(pt, key, false, zeroBlock);
13560 };
13561}
13562
13563// OpenPGP.js - An OpenPGP implementation in javascript
13564
13565const webCrypto$4 = util.getWebCrypto();
13566const nodeCrypto$4 = util.getNodeCrypto();
13567const Buffer$5 = util.getNodeBuffer();
13568
13569
13570const blockLength$2 = 16;
13571const ivLength$1 = blockLength$2;
13572const tagLength$1 = blockLength$2;
13573
13574const zero = new Uint8Array(blockLength$2);
13575const one = new Uint8Array(blockLength$2); one[blockLength$2 - 1] = 1;
13576const two = new Uint8Array(blockLength$2); two[blockLength$2 - 1] = 2;
13577
13578async function OMAC(key) {
13579 const cmac = await CMAC(key);
13580 return function(t, message) {
13581 return cmac(util.concatUint8Array([t, message]));
13582 };
13583}
13584
13585async function CTR(key) {
13586 if (
13587 util.getWebCrypto() &&
13588 key.length !== 24 && // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
13589 navigator.userAgent.indexOf('Edge') === -1
13590 ) {
13591 key = await webCrypto$4.importKey('raw', key, { name: 'AES-CTR', length: key.length * 8 }, false, ['encrypt']);
13592 return async function(pt, iv) {
13593 const ct = await webCrypto$4.encrypt({ name: 'AES-CTR', counter: iv, length: blockLength$2 * 8 }, key, pt);
13594 return new Uint8Array(ct);
13595 };
13596 }
13597 if (util.getNodeCrypto()) { // Node crypto library
13598 key = Buffer$5.from(key);
13599 return async function(pt, iv) {
13600 pt = Buffer$5.from(pt);
13601 iv = Buffer$5.from(iv);
13602 const en = new nodeCrypto$4.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv);
13603 const ct = Buffer$5.concat([en.update(pt), en.final()]);
13604 return new Uint8Array(ct);
13605 };
13606 }
13607 // asm.js fallback
13608 return async function(pt, iv) {
13609 return AES_CTR.encrypt(pt, key, iv);
13610 };
13611}
13612
13613
13614/**
13615 * Class to en/decrypt using EAX mode.
13616 * @param {String} cipher - The symmetric cipher algorithm to use e.g. 'aes128'
13617 * @param {Uint8Array} key - The encryption key
13618 */
13619async function EAX(cipher, key) {
13620 if (cipher.substr(0, 3) !== 'aes') {
13621 throw new Error('EAX mode supports only AES cipher');
13622 }
13623
13624 const [
13625 omac,
13626 ctr
13627 ] = await Promise.all([
13628 OMAC(key),
13629 CTR(key)
13630 ]);
13631
13632 return {
13633 /**
13634 * Encrypt plaintext input.
13635 * @param {Uint8Array} plaintext - The cleartext input to be encrypted
13636 * @param {Uint8Array} nonce - The nonce (16 bytes)
13637 * @param {Uint8Array} adata - Associated data to sign
13638 * @returns {Uint8Array} The ciphertext output.
13639 * @async
13640 */
13641 encrypt: async function(plaintext, nonce, adata) {
13642 const [
13643 omacNonce,
13644 omacAdata
13645 ] = await Promise.all([
13646 omac(zero, nonce),
13647 omac(one, adata)
13648 ]);
13649 const ciphered = await ctr(plaintext, omacNonce);
13650 const omacCiphered = await omac(two, ciphered);
13651 const tag = omacCiphered; // Assumes that omac(*).length === tagLength.
13652 for (let i = 0; i < tagLength$1; i++) {
13653 tag[i] ^= omacAdata[i] ^ omacNonce[i];
13654 }
13655 return util.concatUint8Array([ciphered, tag]);
13656 },
13657
13658 /**
13659 * Decrypt ciphertext input.
13660 * @param {Uint8Array} ciphertext - The ciphertext input to be decrypted
13661 * @param {Uint8Array} nonce - The nonce (16 bytes)
13662 * @param {Uint8Array} adata - Associated data to verify
13663 * @returns {Uint8Array} The plaintext output.
13664 * @async
13665 */
13666 decrypt: async function(ciphertext, nonce, adata) {
13667 if (ciphertext.length < tagLength$1) throw new Error('Invalid EAX ciphertext');
13668 const ciphered = ciphertext.subarray(0, -tagLength$1);
13669 const ctTag = ciphertext.subarray(-tagLength$1);
13670 const [
13671 omacNonce,
13672 omacAdata,
13673 omacCiphered
13674 ] = await Promise.all([
13675 omac(zero, nonce),
13676 omac(one, adata),
13677 omac(two, ciphered)
13678 ]);
13679 const tag = omacCiphered; // Assumes that omac(*).length === tagLength.
13680 for (let i = 0; i < tagLength$1; i++) {
13681 tag[i] ^= omacAdata[i] ^ omacNonce[i];
13682 }
13683 if (!util.equalsUint8Array(ctTag, tag)) throw new Error('Authentication tag mismatch');
13684 const plaintext = await ctr(ciphered, omacNonce);
13685 return plaintext;
13686 }
13687 };
13688}
13689
13690
13691/**
13692 * 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}.
13693 * @param {Uint8Array} iv - The initialization vector (16 bytes)
13694 * @param {Uint8Array} chunkIndex - The chunk index (8 bytes)
13695 */
13696EAX.getNonce = function(iv, chunkIndex) {
13697 const nonce = iv.slice();
13698 for (let i = 0; i < chunkIndex.length; i++) {
13699 nonce[8 + i] ^= chunkIndex[i];
13700 }
13701 return nonce;
13702};
13703
13704EAX.blockLength = blockLength$2;
13705EAX.ivLength = ivLength$1;
13706EAX.tagLength = tagLength$1;
13707
13708// OpenPGP.js - An OpenPGP implementation in javascript
13709
13710
13711const blockLength$3 = 16;
13712const ivLength$2 = 15;
13713
13714// https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16.2:
13715// While OCB [RFC7253] allows the authentication tag length to be of any
13716// number up to 128 bits long, this document requires a fixed
13717// authentication tag length of 128 bits (16 octets) for simplicity.
13718const tagLength$2 = 16;
13719
13720
13721function ntz(n) {
13722 let ntz = 0;
13723 for (let i = 1; (n & i) === 0; i <<= 1) {
13724 ntz++;
13725 }
13726 return ntz;
13727}
13728
13729function xorMut$1(S, T) {
13730 for (let i = 0; i < S.length; i++) {
13731 S[i] ^= T[i];
13732 }
13733 return S;
13734}
13735
13736function xor(S, T) {
13737 return xorMut$1(S.slice(), T);
13738}
13739
13740const zeroBlock$1 = new Uint8Array(blockLength$3);
13741const one$1 = new Uint8Array([1]);
13742
13743/**
13744 * Class to en/decrypt using OCB mode.
13745 * @param {String} cipher - The symmetric cipher algorithm to use e.g. 'aes128'
13746 * @param {Uint8Array} key - The encryption key
13747 */
13748async function OCB(cipher$1, key) {
13749
13750 let maxNtz = 0;
13751 let encipher;
13752 let decipher;
13753 let mask;
13754
13755 constructKeyVariables(cipher$1, key);
13756
13757 function constructKeyVariables(cipher$1, key) {
13758 const aes = new cipher[cipher$1](key);
13759 encipher = aes.encrypt.bind(aes);
13760 decipher = aes.decrypt.bind(aes);
13761
13762 const mask_x = encipher(zeroBlock$1);
13763 const mask_$ = util.double(mask_x);
13764 mask = [];
13765 mask[0] = util.double(mask_$);
13766
13767
13768 mask.x = mask_x;
13769 mask.$ = mask_$;
13770 }
13771
13772 function extendKeyVariables(text, adata) {
13773 const newMaxNtz = util.nbits(Math.max(text.length, adata.length) / blockLength$3 | 0) - 1;
13774 for (let i = maxNtz + 1; i <= newMaxNtz; i++) {
13775 mask[i] = util.double(mask[i - 1]);
13776 }
13777 maxNtz = newMaxNtz;
13778 }
13779
13780 function hash(adata) {
13781 if (!adata.length) {
13782 // Fast path
13783 return zeroBlock$1;
13784 }
13785
13786 //
13787 // Consider A as a sequence of 128-bit blocks
13788 //
13789 const m = adata.length / blockLength$3 | 0;
13790
13791 const offset = new Uint8Array(blockLength$3);
13792 const sum = new Uint8Array(blockLength$3);
13793 for (let i = 0; i < m; i++) {
13794 xorMut$1(offset, mask[ntz(i + 1)]);
13795 xorMut$1(sum, encipher(xor(offset, adata)));
13796 adata = adata.subarray(blockLength$3);
13797 }
13798
13799 //
13800 // Process any final partial block; compute final hash value
13801 //
13802 if (adata.length) {
13803 xorMut$1(offset, mask.x);
13804
13805 const cipherInput = new Uint8Array(blockLength$3);
13806 cipherInput.set(adata, 0);
13807 cipherInput[adata.length] = 0b10000000;
13808 xorMut$1(cipherInput, offset);
13809
13810 xorMut$1(sum, encipher(cipherInput));
13811 }
13812
13813 return sum;
13814 }
13815
13816 /**
13817 * Encrypt/decrypt data.
13818 * @param {encipher|decipher} fn - Encryption/decryption block cipher function
13819 * @param {Uint8Array} text - The cleartext or ciphertext (without tag) input
13820 * @param {Uint8Array} nonce - The nonce (15 bytes)
13821 * @param {Uint8Array} adata - Associated data to sign
13822 * @returns {Uint8Array} The ciphertext or plaintext output, with tag appended in both cases.
13823 */
13824 function crypt(fn, text, nonce, adata) {
13825 //
13826 // Consider P as a sequence of 128-bit blocks
13827 //
13828 const m = text.length / blockLength$3 | 0;
13829
13830 //
13831 // Key-dependent variables
13832 //
13833 extendKeyVariables(text, adata);
13834
13835 //
13836 // Nonce-dependent and per-encryption variables
13837 //
13838 // Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N
13839 // Note: We assume here that tagLength mod 16 == 0.
13840 const paddedNonce = util.concatUint8Array([zeroBlock$1.subarray(0, ivLength$2 - nonce.length), one$1, nonce]);
13841 // bottom = str2num(Nonce[123..128])
13842 const bottom = paddedNonce[blockLength$3 - 1] & 0b111111;
13843 // Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6))
13844 paddedNonce[blockLength$3 - 1] &= 0b11000000;
13845 const kTop = encipher(paddedNonce);
13846 // Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72])
13847 const stretched = util.concatUint8Array([kTop, xor(kTop.subarray(0, 8), kTop.subarray(1, 9))]);
13848 // Offset_0 = Stretch[1+bottom..128+bottom]
13849 const offset = util.shiftRight(stretched.subarray(0 + (bottom >> 3), 17 + (bottom >> 3)), 8 - (bottom & 7)).subarray(1);
13850 // Checksum_0 = zeros(128)
13851 const checksum = new Uint8Array(blockLength$3);
13852
13853 const ct = new Uint8Array(text.length + tagLength$2);
13854
13855 //
13856 // Process any whole blocks
13857 //
13858 let i;
13859 let pos = 0;
13860 for (i = 0; i < m; i++) {
13861 // Offset_i = Offset_{i-1} xor L_{ntz(i)}
13862 xorMut$1(offset, mask[ntz(i + 1)]);
13863 // C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)
13864 // P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)
13865 ct.set(xorMut$1(fn(xor(offset, text)), offset), pos);
13866 // Checksum_i = Checksum_{i-1} xor P_i
13867 xorMut$1(checksum, fn === encipher ? text : ct.subarray(pos));
13868
13869 text = text.subarray(blockLength$3);
13870 pos += blockLength$3;
13871 }
13872
13873 //
13874 // Process any final partial block and compute raw tag
13875 //
13876 if (text.length) {
13877 // Offset_* = Offset_m xor L_*
13878 xorMut$1(offset, mask.x);
13879 // Pad = ENCIPHER(K, Offset_*)
13880 const padding = encipher(offset);
13881 // C_* = P_* xor Pad[1..bitlen(P_*)]
13882 ct.set(xor(text, padding), pos);
13883
13884 // Checksum_* = Checksum_m xor (P_* || 1 || new Uint8Array(127-bitlen(P_*)))
13885 const xorInput = new Uint8Array(blockLength$3);
13886 xorInput.set(fn === encipher ? text : ct.subarray(pos, -tagLength$2), 0);
13887 xorInput[text.length] = 0b10000000;
13888 xorMut$1(checksum, xorInput);
13889 pos += text.length;
13890 }
13891 // Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)
13892 const tag = xorMut$1(encipher(xorMut$1(xorMut$1(checksum, offset), mask.$)), hash(adata));
13893
13894 //
13895 // Assemble ciphertext
13896 //
13897 // C = C_1 || C_2 || ... || C_m || C_* || Tag[1..TAGLEN]
13898 ct.set(tag, pos);
13899 return ct;
13900 }
13901
13902
13903 return {
13904 /**
13905 * Encrypt plaintext input.
13906 * @param {Uint8Array} plaintext - The cleartext input to be encrypted
13907 * @param {Uint8Array} nonce - The nonce (15 bytes)
13908 * @param {Uint8Array} adata - Associated data to sign
13909 * @returns {Uint8Array} The ciphertext output.
13910 * @async
13911 */
13912 encrypt: async function(plaintext, nonce, adata) {
13913 return crypt(encipher, plaintext, nonce, adata);
13914 },
13915
13916 /**
13917 * Decrypt ciphertext input.
13918 * @param {Uint8Array} ciphertext - The ciphertext input to be decrypted
13919 * @param {Uint8Array} nonce - The nonce (15 bytes)
13920 * @param {Uint8Array} adata - Associated data to sign
13921 * @returns {Uint8Array} The ciphertext output.
13922 * @async
13923 */
13924 decrypt: async function(ciphertext, nonce, adata) {
13925 if (ciphertext.length < tagLength$2) throw new Error('Invalid OCB ciphertext');
13926
13927 const tag = ciphertext.subarray(-tagLength$2);
13928 ciphertext = ciphertext.subarray(0, -tagLength$2);
13929
13930 const crypted = crypt(decipher, ciphertext, nonce, adata);
13931 // if (Tag[1..TAGLEN] == T)
13932 if (util.equalsUint8Array(tag, crypted.subarray(-tagLength$2))) {
13933 return crypted.subarray(0, -tagLength$2);
13934 }
13935 throw new Error('Authentication tag mismatch');
13936 }
13937 };
13938}
13939
13940
13941/**
13942 * 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}.
13943 * @param {Uint8Array} iv - The initialization vector (15 bytes)
13944 * @param {Uint8Array} chunkIndex - The chunk index (8 bytes)
13945 */
13946OCB.getNonce = function(iv, chunkIndex) {
13947 const nonce = iv.slice();
13948 for (let i = 0; i < chunkIndex.length; i++) {
13949 nonce[7 + i] ^= chunkIndex[i];
13950 }
13951 return nonce;
13952};
13953
13954OCB.blockLength = blockLength$3;
13955OCB.ivLength = ivLength$2;
13956OCB.tagLength = tagLength$2;
13957
13958var naclFastLight = createCommonjsModule(function (module) {
13959/*jshint bitwise: false*/
13960
13961(function(nacl) {
13962
13963// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
13964// Public domain.
13965//
13966// Implementation derived from TweetNaCl version 20140427.
13967// See for details: http://tweetnacl.cr.yp.to/
13968
13969var gf = function(init) {
13970 var i, r = new Float64Array(16);
13971 if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
13972 return r;
13973};
13974
13975// Pluggable, initialized in high-level API below.
13976var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
13977
13978var _9 = new Uint8Array(32); _9[0] = 9;
13979
13980var gf0 = gf(),
13981 gf1 = gf([1]),
13982 _121665 = gf([0xdb41, 1]),
13983 D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
13984 D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
13985 X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
13986 Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
13987 I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
13988
13989function vn(x, xi, y, yi, n) {
13990 var i,d = 0;
13991 for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
13992 return (1 & ((d - 1) >>> 8)) - 1;
13993}
13994
13995function crypto_verify_32(x, xi, y, yi) {
13996 return vn(x,xi,y,yi,32);
13997}
13998
13999function set25519(r, a) {
14000 var i;
14001 for (i = 0; i < 16; i++) r[i] = a[i]|0;
14002}
14003
14004function car25519(o) {
14005 var i, v, c = 1;
14006 for (i = 0; i < 16; i++) {
14007 v = o[i] + c + 65535;
14008 c = Math.floor(v / 65536);
14009 o[i] = v - c * 65536;
14010 }
14011 o[0] += c-1 + 37 * (c-1);
14012}
14013
14014function sel25519(p, q, b) {
14015 var t, c = ~(b-1);
14016 for (var i = 0; i < 16; i++) {
14017 t = c & (p[i] ^ q[i]);
14018 p[i] ^= t;
14019 q[i] ^= t;
14020 }
14021}
14022
14023function pack25519(o, n) {
14024 var i, j, b;
14025 var m = gf(), t = gf();
14026 for (i = 0; i < 16; i++) t[i] = n[i];
14027 car25519(t);
14028 car25519(t);
14029 car25519(t);
14030 for (j = 0; j < 2; j++) {
14031 m[0] = t[0] - 0xffed;
14032 for (i = 1; i < 15; i++) {
14033 m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
14034 m[i-1] &= 0xffff;
14035 }
14036 m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
14037 b = (m[15]>>16) & 1;
14038 m[14] &= 0xffff;
14039 sel25519(t, m, 1-b);
14040 }
14041 for (i = 0; i < 16; i++) {
14042 o[2*i] = t[i] & 0xff;
14043 o[2*i+1] = t[i]>>8;
14044 }
14045}
14046
14047function neq25519(a, b) {
14048 var c = new Uint8Array(32), d = new Uint8Array(32);
14049 pack25519(c, a);
14050 pack25519(d, b);
14051 return crypto_verify_32(c, 0, d, 0);
14052}
14053
14054function par25519(a) {
14055 var d = new Uint8Array(32);
14056 pack25519(d, a);
14057 return d[0] & 1;
14058}
14059
14060function unpack25519(o, n) {
14061 var i;
14062 for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
14063 o[15] &= 0x7fff;
14064}
14065
14066function A(o, a, b) {
14067 for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
14068}
14069
14070function Z(o, a, b) {
14071 for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
14072}
14073
14074function M(o, a, b) {
14075 var v, c,
14076 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
14077 t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
14078 t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
14079 t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,
14080 b0 = b[0],
14081 b1 = b[1],
14082 b2 = b[2],
14083 b3 = b[3],
14084 b4 = b[4],
14085 b5 = b[5],
14086 b6 = b[6],
14087 b7 = b[7],
14088 b8 = b[8],
14089 b9 = b[9],
14090 b10 = b[10],
14091 b11 = b[11],
14092 b12 = b[12],
14093 b13 = b[13],
14094 b14 = b[14],
14095 b15 = b[15];
14096
14097 v = a[0];
14098 t0 += v * b0;
14099 t1 += v * b1;
14100 t2 += v * b2;
14101 t3 += v * b3;
14102 t4 += v * b4;
14103 t5 += v * b5;
14104 t6 += v * b6;
14105 t7 += v * b7;
14106 t8 += v * b8;
14107 t9 += v * b9;
14108 t10 += v * b10;
14109 t11 += v * b11;
14110 t12 += v * b12;
14111 t13 += v * b13;
14112 t14 += v * b14;
14113 t15 += v * b15;
14114 v = a[1];
14115 t1 += v * b0;
14116 t2 += v * b1;
14117 t3 += v * b2;
14118 t4 += v * b3;
14119 t5 += v * b4;
14120 t6 += v * b5;
14121 t7 += v * b6;
14122 t8 += v * b7;
14123 t9 += v * b8;
14124 t10 += v * b9;
14125 t11 += v * b10;
14126 t12 += v * b11;
14127 t13 += v * b12;
14128 t14 += v * b13;
14129 t15 += v * b14;
14130 t16 += v * b15;
14131 v = a[2];
14132 t2 += v * b0;
14133 t3 += v * b1;
14134 t4 += v * b2;
14135 t5 += v * b3;
14136 t6 += v * b4;
14137 t7 += v * b5;
14138 t8 += v * b6;
14139 t9 += v * b7;
14140 t10 += v * b8;
14141 t11 += v * b9;
14142 t12 += v * b10;
14143 t13 += v * b11;
14144 t14 += v * b12;
14145 t15 += v * b13;
14146 t16 += v * b14;
14147 t17 += v * b15;
14148 v = a[3];
14149 t3 += v * b0;
14150 t4 += v * b1;
14151 t5 += v * b2;
14152 t6 += v * b3;
14153 t7 += v * b4;
14154 t8 += v * b5;
14155 t9 += v * b6;
14156 t10 += v * b7;
14157 t11 += v * b8;
14158 t12 += v * b9;
14159 t13 += v * b10;
14160 t14 += v * b11;
14161 t15 += v * b12;
14162 t16 += v * b13;
14163 t17 += v * b14;
14164 t18 += v * b15;
14165 v = a[4];
14166 t4 += v * b0;
14167 t5 += v * b1;
14168 t6 += v * b2;
14169 t7 += v * b3;
14170 t8 += v * b4;
14171 t9 += v * b5;
14172 t10 += v * b6;
14173 t11 += v * b7;
14174 t12 += v * b8;
14175 t13 += v * b9;
14176 t14 += v * b10;
14177 t15 += v * b11;
14178 t16 += v * b12;
14179 t17 += v * b13;
14180 t18 += v * b14;
14181 t19 += v * b15;
14182 v = a[5];
14183 t5 += v * b0;
14184 t6 += v * b1;
14185 t7 += v * b2;
14186 t8 += v * b3;
14187 t9 += v * b4;
14188 t10 += v * b5;
14189 t11 += v * b6;
14190 t12 += v * b7;
14191 t13 += v * b8;
14192 t14 += v * b9;
14193 t15 += v * b10;
14194 t16 += v * b11;
14195 t17 += v * b12;
14196 t18 += v * b13;
14197 t19 += v * b14;
14198 t20 += v * b15;
14199 v = a[6];
14200 t6 += v * b0;
14201 t7 += v * b1;
14202 t8 += v * b2;
14203 t9 += v * b3;
14204 t10 += v * b4;
14205 t11 += v * b5;
14206 t12 += v * b6;
14207 t13 += v * b7;
14208 t14 += v * b8;
14209 t15 += v * b9;
14210 t16 += v * b10;
14211 t17 += v * b11;
14212 t18 += v * b12;
14213 t19 += v * b13;
14214 t20 += v * b14;
14215 t21 += v * b15;
14216 v = a[7];
14217 t7 += v * b0;
14218 t8 += v * b1;
14219 t9 += v * b2;
14220 t10 += v * b3;
14221 t11 += v * b4;
14222 t12 += v * b5;
14223 t13 += v * b6;
14224 t14 += v * b7;
14225 t15 += v * b8;
14226 t16 += v * b9;
14227 t17 += v * b10;
14228 t18 += v * b11;
14229 t19 += v * b12;
14230 t20 += v * b13;
14231 t21 += v * b14;
14232 t22 += v * b15;
14233 v = a[8];
14234 t8 += v * b0;
14235 t9 += v * b1;
14236 t10 += v * b2;
14237 t11 += v * b3;
14238 t12 += v * b4;
14239 t13 += v * b5;
14240 t14 += v * b6;
14241 t15 += v * b7;
14242 t16 += v * b8;
14243 t17 += v * b9;
14244 t18 += v * b10;
14245 t19 += v * b11;
14246 t20 += v * b12;
14247 t21 += v * b13;
14248 t22 += v * b14;
14249 t23 += v * b15;
14250 v = a[9];
14251 t9 += v * b0;
14252 t10 += v * b1;
14253 t11 += v * b2;
14254 t12 += v * b3;
14255 t13 += v * b4;
14256 t14 += v * b5;
14257 t15 += v * b6;
14258 t16 += v * b7;
14259 t17 += v * b8;
14260 t18 += v * b9;
14261 t19 += v * b10;
14262 t20 += v * b11;
14263 t21 += v * b12;
14264 t22 += v * b13;
14265 t23 += v * b14;
14266 t24 += v * b15;
14267 v = a[10];
14268 t10 += v * b0;
14269 t11 += v * b1;
14270 t12 += v * b2;
14271 t13 += v * b3;
14272 t14 += v * b4;
14273 t15 += v * b5;
14274 t16 += v * b6;
14275 t17 += v * b7;
14276 t18 += v * b8;
14277 t19 += v * b9;
14278 t20 += v * b10;
14279 t21 += v * b11;
14280 t22 += v * b12;
14281 t23 += v * b13;
14282 t24 += v * b14;
14283 t25 += v * b15;
14284 v = a[11];
14285 t11 += v * b0;
14286 t12 += v * b1;
14287 t13 += v * b2;
14288 t14 += v * b3;
14289 t15 += v * b4;
14290 t16 += v * b5;
14291 t17 += v * b6;
14292 t18 += v * b7;
14293 t19 += v * b8;
14294 t20 += v * b9;
14295 t21 += v * b10;
14296 t22 += v * b11;
14297 t23 += v * b12;
14298 t24 += v * b13;
14299 t25 += v * b14;
14300 t26 += v * b15;
14301 v = a[12];
14302 t12 += v * b0;
14303 t13 += v * b1;
14304 t14 += v * b2;
14305 t15 += v * b3;
14306 t16 += v * b4;
14307 t17 += v * b5;
14308 t18 += v * b6;
14309 t19 += v * b7;
14310 t20 += v * b8;
14311 t21 += v * b9;
14312 t22 += v * b10;
14313 t23 += v * b11;
14314 t24 += v * b12;
14315 t25 += v * b13;
14316 t26 += v * b14;
14317 t27 += v * b15;
14318 v = a[13];
14319 t13 += v * b0;
14320 t14 += v * b1;
14321 t15 += v * b2;
14322 t16 += v * b3;
14323 t17 += v * b4;
14324 t18 += v * b5;
14325 t19 += v * b6;
14326 t20 += v * b7;
14327 t21 += v * b8;
14328 t22 += v * b9;
14329 t23 += v * b10;
14330 t24 += v * b11;
14331 t25 += v * b12;
14332 t26 += v * b13;
14333 t27 += v * b14;
14334 t28 += v * b15;
14335 v = a[14];
14336 t14 += v * b0;
14337 t15 += v * b1;
14338 t16 += v * b2;
14339 t17 += v * b3;
14340 t18 += v * b4;
14341 t19 += v * b5;
14342 t20 += v * b6;
14343 t21 += v * b7;
14344 t22 += v * b8;
14345 t23 += v * b9;
14346 t24 += v * b10;
14347 t25 += v * b11;
14348 t26 += v * b12;
14349 t27 += v * b13;
14350 t28 += v * b14;
14351 t29 += v * b15;
14352 v = a[15];
14353 t15 += v * b0;
14354 t16 += v * b1;
14355 t17 += v * b2;
14356 t18 += v * b3;
14357 t19 += v * b4;
14358 t20 += v * b5;
14359 t21 += v * b6;
14360 t22 += v * b7;
14361 t23 += v * b8;
14362 t24 += v * b9;
14363 t25 += v * b10;
14364 t26 += v * b11;
14365 t27 += v * b12;
14366 t28 += v * b13;
14367 t29 += v * b14;
14368 t30 += v * b15;
14369
14370 t0 += 38 * t16;
14371 t1 += 38 * t17;
14372 t2 += 38 * t18;
14373 t3 += 38 * t19;
14374 t4 += 38 * t20;
14375 t5 += 38 * t21;
14376 t6 += 38 * t22;
14377 t7 += 38 * t23;
14378 t8 += 38 * t24;
14379 t9 += 38 * t25;
14380 t10 += 38 * t26;
14381 t11 += 38 * t27;
14382 t12 += 38 * t28;
14383 t13 += 38 * t29;
14384 t14 += 38 * t30;
14385 // t15 left as is
14386
14387 // first car
14388 c = 1;
14389 v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
14390 v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
14391 v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
14392 v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
14393 v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
14394 v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
14395 v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
14396 v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
14397 v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
14398 v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
14399 v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
14400 v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
14401 v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
14402 v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
14403 v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
14404 v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
14405 t0 += c-1 + 37 * (c-1);
14406
14407 // second car
14408 c = 1;
14409 v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
14410 v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
14411 v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
14412 v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
14413 v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
14414 v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
14415 v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
14416 v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
14417 v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
14418 v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
14419 v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
14420 v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
14421 v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
14422 v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
14423 v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
14424 v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
14425 t0 += c-1 + 37 * (c-1);
14426
14427 o[ 0] = t0;
14428 o[ 1] = t1;
14429 o[ 2] = t2;
14430 o[ 3] = t3;
14431 o[ 4] = t4;
14432 o[ 5] = t5;
14433 o[ 6] = t6;
14434 o[ 7] = t7;
14435 o[ 8] = t8;
14436 o[ 9] = t9;
14437 o[10] = t10;
14438 o[11] = t11;
14439 o[12] = t12;
14440 o[13] = t13;
14441 o[14] = t14;
14442 o[15] = t15;
14443}
14444
14445function S(o, a) {
14446 M(o, a, a);
14447}
14448
14449function inv25519(o, i) {
14450 var c = gf();
14451 var a;
14452 for (a = 0; a < 16; a++) c[a] = i[a];
14453 for (a = 253; a >= 0; a--) {
14454 S(c, c);
14455 if(a !== 2 && a !== 4) M(c, c, i);
14456 }
14457 for (a = 0; a < 16; a++) o[a] = c[a];
14458}
14459
14460function pow2523(o, i) {
14461 var c = gf();
14462 var a;
14463 for (a = 0; a < 16; a++) c[a] = i[a];
14464 for (a = 250; a >= 0; a--) {
14465 S(c, c);
14466 if(a !== 1) M(c, c, i);
14467 }
14468 for (a = 0; a < 16; a++) o[a] = c[a];
14469}
14470
14471function crypto_scalarmult(q, n, p) {
14472 var z = new Uint8Array(32);
14473 var x = new Float64Array(80), r, i;
14474 var a = gf(), b = gf(), c = gf(),
14475 d = gf(), e = gf(), f = gf();
14476 for (i = 0; i < 31; i++) z[i] = n[i];
14477 z[31]=(n[31]&127)|64;
14478 z[0]&=248;
14479 unpack25519(x,p);
14480 for (i = 0; i < 16; i++) {
14481 b[i]=x[i];
14482 d[i]=a[i]=c[i]=0;
14483 }
14484 a[0]=d[0]=1;
14485 for (i=254; i>=0; --i) {
14486 r=(z[i>>>3]>>>(i&7))&1;
14487 sel25519(a,b,r);
14488 sel25519(c,d,r);
14489 A(e,a,c);
14490 Z(a,a,c);
14491 A(c,b,d);
14492 Z(b,b,d);
14493 S(d,e);
14494 S(f,a);
14495 M(a,c,a);
14496 M(c,b,e);
14497 A(e,a,c);
14498 Z(a,a,c);
14499 S(b,a);
14500 Z(c,d,f);
14501 M(a,c,_121665);
14502 A(a,a,d);
14503 M(c,c,a);
14504 M(a,d,f);
14505 M(d,b,x);
14506 S(b,e);
14507 sel25519(a,b,r);
14508 sel25519(c,d,r);
14509 }
14510 for (i = 0; i < 16; i++) {
14511 x[i+16]=a[i];
14512 x[i+32]=c[i];
14513 x[i+48]=b[i];
14514 x[i+64]=d[i];
14515 }
14516 var x32 = x.subarray(32);
14517 var x16 = x.subarray(16);
14518 inv25519(x32,x32);
14519 M(x16,x16,x32);
14520 pack25519(q,x16);
14521 return 0;
14522}
14523
14524function crypto_scalarmult_base(q, n) {
14525 return crypto_scalarmult(q, n, _9);
14526}
14527
14528function crypto_box_keypair(y, x) {
14529 randombytes(x, 32);
14530 return crypto_scalarmult_base(y, x);
14531}
14532
14533function add(p, q) {
14534 var a = gf(), b = gf(), c = gf(),
14535 d = gf(), e = gf(), f = gf(),
14536 g = gf(), h = gf(), t = gf();
14537
14538 Z(a, p[1], p[0]);
14539 Z(t, q[1], q[0]);
14540 M(a, a, t);
14541 A(b, p[0], p[1]);
14542 A(t, q[0], q[1]);
14543 M(b, b, t);
14544 M(c, p[3], q[3]);
14545 M(c, c, D2);
14546 M(d, p[2], q[2]);
14547 A(d, d, d);
14548 Z(e, b, a);
14549 Z(f, d, c);
14550 A(g, d, c);
14551 A(h, b, a);
14552
14553 M(p[0], e, f);
14554 M(p[1], h, g);
14555 M(p[2], g, f);
14556 M(p[3], e, h);
14557}
14558
14559function cswap(p, q, b) {
14560 var i;
14561 for (i = 0; i < 4; i++) {
14562 sel25519(p[i], q[i], b);
14563 }
14564}
14565
14566function pack(r, p) {
14567 var tx = gf(), ty = gf(), zi = gf();
14568 inv25519(zi, p[2]);
14569 M(tx, p[0], zi);
14570 M(ty, p[1], zi);
14571 pack25519(r, ty);
14572 r[31] ^= par25519(tx) << 7;
14573}
14574
14575function scalarmult(p, q, s) {
14576 var b, i;
14577 set25519(p[0], gf0);
14578 set25519(p[1], gf1);
14579 set25519(p[2], gf1);
14580 set25519(p[3], gf0);
14581 for (i = 255; i >= 0; --i) {
14582 b = (s[(i/8)|0] >> (i&7)) & 1;
14583 cswap(p, q, b);
14584 add(q, p);
14585 add(p, p);
14586 cswap(p, q, b);
14587 }
14588}
14589
14590function scalarbase(p, s) {
14591 var q = [gf(), gf(), gf(), gf()];
14592 set25519(q[0], X);
14593 set25519(q[1], Y);
14594 set25519(q[2], gf1);
14595 M(q[3], X, Y);
14596 scalarmult(p, q, s);
14597}
14598
14599function crypto_sign_keypair(pk, sk, seeded) {
14600 var d;
14601 var p = [gf(), gf(), gf(), gf()];
14602 var i;
14603
14604 if (!seeded) randombytes(sk, 32);
14605 d = nacl.hash(sk.subarray(0, 32));
14606 d[0] &= 248;
14607 d[31] &= 127;
14608 d[31] |= 64;
14609
14610 scalarbase(p, d);
14611 pack(pk, p);
14612
14613 for (i = 0; i < 32; i++) sk[i+32] = pk[i];
14614 return 0;
14615}
14616
14617var 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]);
14618
14619function modL(r, x) {
14620 var carry, i, j, k;
14621 for (i = 63; i >= 32; --i) {
14622 carry = 0;
14623 for (j = i - 32, k = i - 12; j < k; ++j) {
14624 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
14625 carry = Math.floor((x[j] + 128) / 256);
14626 x[j] -= carry * 256;
14627 }
14628 x[j] += carry;
14629 x[i] = 0;
14630 }
14631 carry = 0;
14632 for (j = 0; j < 32; j++) {
14633 x[j] += carry - (x[31] >> 4) * L[j];
14634 carry = x[j] >> 8;
14635 x[j] &= 255;
14636 }
14637 for (j = 0; j < 32; j++) x[j] -= carry * L[j];
14638 for (i = 0; i < 32; i++) {
14639 x[i+1] += x[i] >> 8;
14640 r[i] = x[i] & 255;
14641 }
14642}
14643
14644function reduce(r) {
14645 var x = new Float64Array(64), i;
14646 for (i = 0; i < 64; i++) x[i] = r[i];
14647 for (i = 0; i < 64; i++) r[i] = 0;
14648 modL(r, x);
14649}
14650
14651// Note: difference from C - smlen returned, not passed as argument.
14652function crypto_sign(sm, m, n, sk) {
14653 var d, h, r;
14654 var i, j, x = new Float64Array(64);
14655 var p = [gf(), gf(), gf(), gf()];
14656
14657 d = nacl.hash(sk.subarray(0, 32));
14658 d[0] &= 248;
14659 d[31] &= 127;
14660 d[31] |= 64;
14661
14662 var smlen = n + 64;
14663 for (i = 0; i < n; i++) sm[64 + i] = m[i];
14664 for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
14665
14666 r = nacl.hash(sm.subarray(32, smlen));
14667 reduce(r);
14668 scalarbase(p, r);
14669 pack(sm, p);
14670
14671 for (i = 32; i < 64; i++) sm[i] = sk[i];
14672 h = nacl.hash(sm.subarray(0, smlen));
14673 reduce(h);
14674
14675 for (i = 0; i < 64; i++) x[i] = 0;
14676 for (i = 0; i < 32; i++) x[i] = r[i];
14677 for (i = 0; i < 32; i++) {
14678 for (j = 0; j < 32; j++) {
14679 x[i+j] += h[i] * d[j];
14680 }
14681 }
14682
14683 modL(sm.subarray(32), x);
14684 return smlen;
14685}
14686
14687function unpackneg(r, p) {
14688 var t = gf(), chk = gf(), num = gf(),
14689 den = gf(), den2 = gf(), den4 = gf(),
14690 den6 = gf();
14691
14692 set25519(r[2], gf1);
14693 unpack25519(r[1], p);
14694 S(num, r[1]);
14695 M(den, num, D);
14696 Z(num, num, r[2]);
14697 A(den, r[2], den);
14698
14699 S(den2, den);
14700 S(den4, den2);
14701 M(den6, den4, den2);
14702 M(t, den6, num);
14703 M(t, t, den);
14704
14705 pow2523(t, t);
14706 M(t, t, num);
14707 M(t, t, den);
14708 M(t, t, den);
14709 M(r[0], t, den);
14710
14711 S(chk, r[0]);
14712 M(chk, chk, den);
14713 if (neq25519(chk, num)) M(r[0], r[0], I);
14714
14715 S(chk, r[0]);
14716 M(chk, chk, den);
14717 if (neq25519(chk, num)) return -1;
14718
14719 if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
14720
14721 M(r[3], r[0], r[1]);
14722 return 0;
14723}
14724
14725function crypto_sign_open(m, sm, n, pk) {
14726 var i;
14727 var t = new Uint8Array(32), h;
14728 var p = [gf(), gf(), gf(), gf()],
14729 q = [gf(), gf(), gf(), gf()];
14730
14731 if (n < 64) return -1;
14732
14733 if (unpackneg(q, pk)) return -1;
14734
14735 for (i = 0; i < n; i++) m[i] = sm[i];
14736 for (i = 0; i < 32; i++) m[i+32] = pk[i];
14737 h = nacl.hash(m.subarray(0, n));
14738 reduce(h);
14739 scalarmult(p, q, h);
14740
14741 scalarbase(q, sm.subarray(32));
14742 add(p, q);
14743 pack(t, p);
14744
14745 n -= 64;
14746 if (crypto_verify_32(sm, 0, t, 0)) {
14747 for (i = 0; i < n; i++) m[i] = 0;
14748 return -1;
14749 }
14750
14751 for (i = 0; i < n; i++) m[i] = sm[i + 64];
14752 return n;
14753}
14754
14755var crypto_scalarmult_BYTES = 32,
14756 crypto_scalarmult_SCALARBYTES = 32,
14757 crypto_box_PUBLICKEYBYTES = 32,
14758 crypto_box_SECRETKEYBYTES = 32,
14759 crypto_sign_BYTES = 64,
14760 crypto_sign_PUBLICKEYBYTES = 32,
14761 crypto_sign_SECRETKEYBYTES = 64,
14762 crypto_sign_SEEDBYTES = 32;
14763
14764function checkArrayTypes() {
14765 for (var i = 0; i < arguments.length; i++) {
14766 if (!(arguments[i] instanceof Uint8Array))
14767 throw new TypeError('unexpected type, use Uint8Array');
14768 }
14769}
14770
14771function cleanup(arr) {
14772 for (var i = 0; i < arr.length; i++) arr[i] = 0;
14773}
14774
14775nacl.scalarMult = function(n, p) {
14776 checkArrayTypes(n, p);
14777 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
14778 if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
14779 var q = new Uint8Array(crypto_scalarmult_BYTES);
14780 crypto_scalarmult(q, n, p);
14781 return q;
14782};
14783
14784nacl.box = {};
14785
14786nacl.box.keyPair = function() {
14787 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
14788 var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
14789 crypto_box_keypair(pk, sk);
14790 return {publicKey: pk, secretKey: sk};
14791};
14792
14793nacl.box.keyPair.fromSecretKey = function(secretKey) {
14794 checkArrayTypes(secretKey);
14795 if (secretKey.length !== crypto_box_SECRETKEYBYTES)
14796 throw new Error('bad secret key size');
14797 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
14798 crypto_scalarmult_base(pk, secretKey);
14799 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
14800};
14801
14802nacl.sign = function(msg, secretKey) {
14803 checkArrayTypes(msg, secretKey);
14804 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
14805 throw new Error('bad secret key size');
14806 var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
14807 crypto_sign(signedMsg, msg, msg.length, secretKey);
14808 return signedMsg;
14809};
14810
14811nacl.sign.detached = function(msg, secretKey) {
14812 var signedMsg = nacl.sign(msg, secretKey);
14813 var sig = new Uint8Array(crypto_sign_BYTES);
14814 for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
14815 return sig;
14816};
14817
14818nacl.sign.detached.verify = function(msg, sig, publicKey) {
14819 checkArrayTypes(msg, sig, publicKey);
14820 if (sig.length !== crypto_sign_BYTES)
14821 throw new Error('bad signature size');
14822 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
14823 throw new Error('bad public key size');
14824 var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
14825 var m = new Uint8Array(crypto_sign_BYTES + msg.length);
14826 var i;
14827 for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
14828 for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
14829 return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
14830};
14831
14832nacl.sign.keyPair = function() {
14833 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
14834 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
14835 crypto_sign_keypair(pk, sk);
14836 return {publicKey: pk, secretKey: sk};
14837};
14838
14839nacl.sign.keyPair.fromSecretKey = function(secretKey) {
14840 checkArrayTypes(secretKey);
14841 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
14842 throw new Error('bad secret key size');
14843 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
14844 for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];
14845 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
14846};
14847
14848nacl.sign.keyPair.fromSeed = function(seed) {
14849 checkArrayTypes(seed);
14850 if (seed.length !== crypto_sign_SEEDBYTES)
14851 throw new Error('bad seed size');
14852 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
14853 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
14854 for (var i = 0; i < 32; i++) sk[i] = seed[i];
14855 crypto_sign_keypair(pk, sk, true);
14856 return {publicKey: pk, secretKey: sk};
14857};
14858
14859nacl.setPRNG = function(fn) {
14860 randombytes = fn;
14861};
14862
14863(function() {
14864 // Initialize PRNG if environment provides CSPRNG.
14865 // If not, methods calling randombytes will throw.
14866 var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
14867 if (crypto && crypto.getRandomValues) {
14868 // Browsers.
14869 var QUOTA = 65536;
14870 nacl.setPRNG(function(x, n) {
14871 var i, v = new Uint8Array(n);
14872 for (i = 0; i < n; i += QUOTA) {
14873 crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
14874 }
14875 for (i = 0; i < n; i++) x[i] = v[i];
14876 cleanup(v);
14877 });
14878 } else if (typeof commonjsRequire !== 'undefined') {
14879 // Node.js.
14880 crypto = void('crypto');
14881 if (crypto && crypto.randomBytes) {
14882 nacl.setPRNG(function(x, n) {
14883 var i, v = crypto.randomBytes(n);
14884 for (i = 0; i < n; i++) x[i] = v[i];
14885 cleanup(v);
14886 });
14887 }
14888 }
14889})();
14890
14891})(module.exports ? module.exports : (self.nacl = self.nacl || {}));
14892});
14893
14894// GPG4Browsers - An OpenPGP implementation in javascript
14895
14896const nodeCrypto$5 = util.getNodeCrypto();
14897
14898/**
14899 * Buffer for secure random numbers
14900 */
14901class RandomBuffer {
14902 constructor() {
14903 this.buffer = null;
14904 this.size = null;
14905 this.callback = null;
14906 }
14907
14908 /**
14909 * Initialize buffer
14910 * @param {Integer} size - size of buffer
14911 */
14912 init(size, callback) {
14913 this.buffer = new Uint8Array(size);
14914 this.size = 0;
14915 this.callback = callback;
14916 }
14917
14918 /**
14919 * Concat array of secure random numbers to buffer
14920 * @param {Uint8Array} buf
14921 */
14922 set(buf) {
14923 if (!this.buffer) {
14924 throw new Error('RandomBuffer is not initialized');
14925 }
14926 if (!(buf instanceof Uint8Array)) {
14927 throw new Error('Invalid type: buf not an Uint8Array');
14928 }
14929 const freeSpace = this.buffer.length - this.size;
14930 if (buf.length > freeSpace) {
14931 buf = buf.subarray(0, freeSpace);
14932 }
14933 // set buf with offset old size of buffer
14934 this.buffer.set(buf, this.size);
14935 this.size += buf.length;
14936 }
14937
14938 /**
14939 * Take numbers out of buffer and copy to array
14940 * @param {Uint8Array} buf - The destination array
14941 */
14942 async get(buf) {
14943 if (!this.buffer) {
14944 throw new Error('RandomBuffer is not initialized');
14945 }
14946 if (!(buf instanceof Uint8Array)) {
14947 throw new Error('Invalid type: buf not an Uint8Array');
14948 }
14949 if (this.size < buf.length) {
14950 if (!this.callback) {
14951 throw new Error('Random number buffer depleted');
14952 }
14953 // Wait for random bytes from main context, then try again
14954 await this.callback();
14955 return this.get(buf);
14956 }
14957 for (let i = 0; i < buf.length; i++) {
14958 buf[i] = this.buffer[--this.size];
14959 // clear buffer value
14960 this.buffer[this.size] = 0;
14961 }
14962 }
14963}
14964
14965/**
14966 * Retrieve secure random byte array of the specified length
14967 * @param {Integer} length - Length in bytes to generate
14968 * @returns {Uint8Array} Random byte array.
14969 * @async
14970 */
14971async function getRandomBytes(length) {
14972 const buf = new Uint8Array(length);
14973 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
14974 crypto.getRandomValues(buf);
14975 } else if (typeof globalThis !== 'undefined' && typeof globalThis.msCrypto === 'object' && typeof globalThis.msCrypto.getRandomValues === 'function') {
14976 globalThis.msCrypto.getRandomValues(buf);
14977 } else if (nodeCrypto$5) {
14978 const bytes = nodeCrypto$5.randomBytes(buf.length);
14979 buf.set(bytes);
14980 } else if (randomBuffer.buffer) {
14981 await randomBuffer.get(buf);
14982 } else {
14983 throw new Error('No secure random number generator available.');
14984 }
14985 return buf;
14986}
14987
14988/**
14989 * Create a secure random BigInteger that is greater than or equal to min and less than max.
14990 * @param {module:BigInteger} min - Lower bound, included
14991 * @param {module:BigInteger} max - Upper bound, excluded
14992 * @returns {module:BigInteger} Random BigInteger.
14993 * @async
14994 */
14995async function getRandomBigInteger(min, max) {
14996 const BigInteger = await util.getBigInteger();
14997
14998 if (max.lt(min)) {
14999 throw new Error('Illegal parameter value: max <= min');
15000 }
15001
15002 const modulus = max.sub(min);
15003 const bytes = modulus.byteLength();
15004
15005 // Using a while loop is necessary to avoid bias introduced by the mod operation.
15006 // However, we request 64 extra random bits so that the bias is negligible.
15007 // Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
15008 const r = new BigInteger(await getRandomBytes(bytes + 8));
15009 return r.mod(modulus).add(min);
15010}
15011
15012const randomBuffer = new RandomBuffer();
15013
15014var random = /*#__PURE__*/Object.freeze({
15015 __proto__: null,
15016 getRandomBytes: getRandomBytes,
15017 getRandomBigInteger: getRandomBigInteger,
15018 randomBuffer: randomBuffer
15019});
15020
15021// OpenPGP.js - An OpenPGP implementation in javascript
15022
15023/**
15024 * Probabilistic random number generator
15025 * @param {Integer} bits - Bit length of the prime
15026 * @param {BigInteger} e - Optional RSA exponent to check against the prime
15027 * @param {Integer} k - Optional number of iterations of Miller-Rabin test
15028 * @returns BigInteger
15029 * @async
15030 */
15031async function randomProbablePrime(bits, e, k) {
15032 const BigInteger = await util.getBigInteger();
15033 const one = new BigInteger(1);
15034 const min = one.leftShift(new BigInteger(bits - 1));
15035 const thirty = new BigInteger(30);
15036 /*
15037 * We can avoid any multiples of 3 and 5 by looking at n mod 30
15038 * 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
15039 * the next possible prime is mod 30:
15040 * 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
15041 */
15042 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];
15043
15044 const n = await getRandomBigInteger(min, min.leftShift(one));
15045 let i = n.mod(thirty).toNumber();
15046
15047 do {
15048 n.iadd(new BigInteger(adds[i]));
15049 i = (i + adds[i]) % adds.length;
15050 // If reached the maximum, go back to the minimum.
15051 if (n.bitLength() > bits) {
15052 n.imod(min.leftShift(one)).iadd(min);
15053 i = n.mod(thirty).toNumber();
15054 }
15055 } while (!await isProbablePrime(n, e, k));
15056 return n;
15057}
15058
15059/**
15060 * Probabilistic primality testing
15061 * @param {BigInteger} n - Number to test
15062 * @param {BigInteger} e - Optional RSA exponent to check against the prime
15063 * @param {Integer} k - Optional number of iterations of Miller-Rabin test
15064 * @returns {boolean}
15065 * @async
15066 */
15067async function isProbablePrime(n, e, k) {
15068 if (e && !n.dec().gcd(e).isOne()) {
15069 return false;
15070 }
15071 if (!await divisionTest(n)) {
15072 return false;
15073 }
15074 if (!await fermat(n)) {
15075 return false;
15076 }
15077 if (!await millerRabin(n, k)) {
15078 return false;
15079 }
15080 // TODO implement the Lucas test
15081 // See Section C.3.3 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
15082 return true;
15083}
15084
15085/**
15086 * Tests whether n is probably prime or not using Fermat's test with b = 2.
15087 * Fails if b^(n-1) mod n != 1.
15088 * @param {BigInteger} n - Number to test
15089 * @param {BigInteger} b - Optional Fermat test base
15090 * @returns {boolean}
15091 */
15092async function fermat(n, b) {
15093 const BigInteger = await util.getBigInteger();
15094 b = b || new BigInteger(2);
15095 return b.modExp(n.dec(), n).isOne();
15096}
15097
15098async function divisionTest(n) {
15099 const BigInteger = await util.getBigInteger();
15100 return smallPrimes.every(m => {
15101 return n.mod(new BigInteger(m)) !== 0;
15102 });
15103}
15104
15105// https://github.com/gpg/libgcrypt/blob/master/cipher/primegen.c
15106const smallPrimes = [
15107 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
15108 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
15109 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
15110 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
15111 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
15112 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
15113 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
15114 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
15115 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
15116 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
15117 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
15118 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
15119 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
15120 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
15121 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
15122 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
15123 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
15124 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
15125 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
15126 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
15127 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
15128 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
15129 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
15130 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
15131 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
15132 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
15133 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
15134 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
15135 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
15136 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
15137 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
15138 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
15139 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
15140 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
15141 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
15142 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
15143 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
15144 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
15145 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
15146 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
15147 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
15148 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
15149 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
15150 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
15151 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
15152 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
15153 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
15154 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
15155 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
15156 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
15157 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
15158 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
15159 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
15160 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
15161 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
15162 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
15163 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
15164 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
15165 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
15166 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
15167 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
15168 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
15169 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
15170 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
15171 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
15172 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
15173 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
15174 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
15175 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
15176 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
15177 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
15178 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
15179 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
15180 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
15181 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
15182 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
15183 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
15184 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
15185 4957, 4967, 4969, 4973, 4987, 4993, 4999
15186];
15187
15188
15189// Miller-Rabin - Miller Rabin algorithm for primality test
15190// Copyright Fedor Indutny, 2014.
15191//
15192// This software is licensed under the MIT License.
15193//
15194// Permission is hereby granted, free of charge, to any person obtaining a
15195// copy of this software and associated documentation files (the
15196// "Software"), to deal in the Software without restriction, including
15197// without limitation the rights to use, copy, modify, merge, publish,
15198// distribute, sublicense, and/or sell copies of the Software, and to permit
15199// persons to whom the Software is furnished to do so, subject to the
15200// following conditions:
15201//
15202// The above copyright notice and this permission notice shall be included
15203// in all copies or substantial portions of the Software.
15204//
15205// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15206// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15207// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
15208// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15209// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15210// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
15211// USE OR OTHER DEALINGS IN THE SOFTWARE.
15212
15213// Adapted on Jan 2018 from version 4.0.1 at https://github.com/indutny/miller-rabin
15214
15215// Sample syntax for Fixed-Base Miller-Rabin:
15216// millerRabin(n, k, () => new BN(small_primes[Math.random() * small_primes.length | 0]))
15217
15218/**
15219 * Tests whether n is probably prime or not using the Miller-Rabin test.
15220 * See HAC Remark 4.28.
15221 * @param {BigInteger} n - Number to test
15222 * @param {Integer} k - Optional number of iterations of Miller-Rabin test
15223 * @param {Function} rand - Optional function to generate potential witnesses
15224 * @returns {boolean}
15225 * @async
15226 */
15227async function millerRabin(n, k, rand) {
15228 const BigInteger = await util.getBigInteger();
15229 const len = n.bitLength();
15230
15231 if (!k) {
15232 k = Math.max(1, (len / 48) | 0);
15233 }
15234
15235 const n1 = n.dec(); // n - 1
15236
15237 // Find d and s, (n - 1) = (2 ^ s) * d;
15238 let s = 0;
15239 while (!n1.getBit(s)) { s++; }
15240 const d = n.rightShift(new BigInteger(s));
15241
15242 for (; k > 0; k--) {
15243 const a = rand ? rand() : await getRandomBigInteger(new BigInteger(2), n1);
15244
15245 let x = a.modExp(d, n);
15246 if (x.isOne() || x.equal(n1)) {
15247 continue;
15248 }
15249
15250 let i;
15251 for (i = 1; i < s; i++) {
15252 x = x.mul(x).mod(n);
15253
15254 if (x.isOne()) {
15255 return false;
15256 }
15257 if (x.equal(n1)) {
15258 break;
15259 }
15260 }
15261
15262 if (i === s) {
15263 return false;
15264 }
15265 }
15266
15267 return true;
15268}
15269
15270// GPG4Browsers - An OpenPGP implementation in javascript
15271
15272/**
15273 * ASN1 object identifiers for hashes
15274 * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.2}
15275 */
15276const hash_headers = [];
15277hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04,
15278 0x10];
15279hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14];
15280hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14];
15281hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
15282 0x04, 0x20];
15283hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
15284 0x04, 0x30];
15285hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
15286 0x00, 0x04, 0x40];
15287hash_headers[11] = [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
15288 0x00, 0x04, 0x1C];
15289
15290/**
15291 * Create padding with secure random data
15292 * @private
15293 * @param {Integer} length - Length of the padding in bytes
15294 * @returns {Uint8Array} Random padding.
15295 * @async
15296 */
15297async function getPkcs1Padding(length) {
15298 const result = new Uint8Array(length);
15299 let count = 0;
15300 while (count < length) {
15301 const randomBytes = await getRandomBytes(length - count);
15302 for (let i = 0; i < randomBytes.length; i++) {
15303 if (randomBytes[i] !== 0) {
15304 result[count++] = randomBytes[i];
15305 }
15306 }
15307 }
15308 return result;
15309}
15310
15311/**
15312 * Create a EME-PKCS1-v1_5 padded message
15313 * @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.1|RFC 4880 13.1.1}
15314 * @param {Uint8Array} message - Message to be encoded
15315 * @param {Integer} keyLength - The length in octets of the key modulus
15316 * @returns {Uint8Array} EME-PKCS1 padded message.
15317 * @async
15318 */
15319async function emeEncode(message, keyLength) {
15320 const mLength = message.length;
15321 // length checking
15322 if (mLength > keyLength - 11) {
15323 throw new Error('Message too long');
15324 }
15325 // Generate an octet string PS of length k - mLen - 3 consisting of
15326 // pseudo-randomly generated nonzero octets
15327 const PS = await getPkcs1Padding(keyLength - mLength - 3);
15328 // Concatenate PS, the message M, and other padding to form an
15329 // encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M.
15330 const encoded = new Uint8Array(keyLength);
15331 // 0x00 byte
15332 encoded[1] = 2;
15333 encoded.set(PS, 2);
15334 // 0x00 bytes
15335 encoded.set(message, keyLength - mLength);
15336 return encoded;
15337}
15338
15339/**
15340 * Decode a EME-PKCS1-v1_5 padded message
15341 * @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.2|RFC 4880 13.1.2}
15342 * @param {Uint8Array} encoded - Encoded message bytes
15343 * @returns {Uint8Array} Message.
15344 */
15345function emeDecode(encoded) {
15346 let i = 2;
15347 while (encoded[i] !== 0 && i < encoded.length) {
15348 i++;
15349 }
15350 const psLen = i - 2;
15351 const separator = encoded[i++];
15352 if (encoded[0] === 0 && encoded[1] === 2 && psLen >= 8 && separator === 0) {
15353 return encoded.subarray(i);
15354 }
15355 throw new Error('Decryption error');
15356}
15357
15358/**
15359 * Create a EMSA-PKCS1-v1_5 padded message
15360 * @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.3|RFC 4880 13.1.3}
15361 * @param {Integer} algo - Hash algorithm type used
15362 * @param {Uint8Array} hashed - Message to be encoded
15363 * @param {Integer} emLen - Intended length in octets of the encoded message
15364 * @returns {Uint8Array} Encoded message.
15365 */
15366async function emsaEncode(algo, hashed, emLen) {
15367 let i;
15368 if (hashed.length !== hash.getHashByteLength(algo)) {
15369 throw new Error('Invalid hash length');
15370 }
15371 // produce an ASN.1 DER value for the hash function used.
15372 // Let T be the full hash prefix
15373 const hashPrefix = new Uint8Array(hash_headers[algo].length);
15374 for (i = 0; i < hash_headers[algo].length; i++) {
15375 hashPrefix[i] = hash_headers[algo][i];
15376 }
15377 // and let tLen be the length in octets prefix and hashed data
15378 const tLen = hashPrefix.length + hashed.length;
15379 if (emLen < tLen + 11) {
15380 throw new Error('Intended encoded message length too short');
15381 }
15382 // an octet string PS consisting of emLen - tLen - 3 octets with hexadecimal value 0xFF
15383 // The length of PS will be at least 8 octets
15384 const PS = new Uint8Array(emLen - tLen - 3).fill(0xff);
15385
15386 // Concatenate PS, the hash prefix, hashed data, and other padding to form the
15387 // encoded message EM as EM = 0x00 || 0x01 || PS || 0x00 || prefix || hashed
15388 const EM = new Uint8Array(emLen);
15389 EM[1] = 0x01;
15390 EM.set(PS, 2);
15391 EM.set(hashPrefix, emLen - tLen);
15392 EM.set(hashed, emLen - hashed.length);
15393 return EM;
15394}
15395
15396var pkcs1 = /*#__PURE__*/Object.freeze({
15397 __proto__: null,
15398 emeEncode: emeEncode,
15399 emeDecode: emeDecode,
15400 emsaEncode: emsaEncode
15401});
15402
15403// GPG4Browsers - An OpenPGP implementation in javascript
15404
15405const webCrypto$5 = util.getWebCrypto();
15406const nodeCrypto$6 = util.getNodeCrypto();
15407const asn1 = nodeCrypto$6 ? void('asn1.js') : undefined;
15408
15409// Helper for IE11 KeyOperation objects
15410function promisifyIE11Op(keyObj, err) {
15411 if (typeof keyObj.then !== 'function') { // IE11 KeyOperation
15412 return new Promise(function(resolve, reject) {
15413 keyObj.onerror = function () {
15414 reject(new Error(err));
15415 };
15416 keyObj.oncomplete = function (e) {
15417 resolve(e.target.result);
15418 };
15419 });
15420 }
15421 return keyObj;
15422}
15423
15424/* eslint-disable no-invalid-this */
15425const RSAPrivateKey = util.detectNode() ? asn1.define('RSAPrivateKey', function () {
15426 this.seq().obj( // used for native NodeJS crypto
15427 this.key('version').int(), // 0
15428 this.key('modulus').int(), // n
15429 this.key('publicExponent').int(), // e
15430 this.key('privateExponent').int(), // d
15431 this.key('prime1').int(), // p
15432 this.key('prime2').int(), // q
15433 this.key('exponent1').int(), // dp
15434 this.key('exponent2').int(), // dq
15435 this.key('coefficient').int() // u
15436 );
15437}) : undefined;
15438
15439const RSAPublicKey = util.detectNode() ? asn1.define('RSAPubliceKey', function () {
15440 this.seq().obj( // used for native NodeJS crypto
15441 this.key('modulus').int(), // n
15442 this.key('publicExponent').int(), // e
15443 );
15444}) : undefined;
15445/* eslint-enable no-invalid-this */
15446
15447/** Create signature
15448 * @param {module:enums.hash} hash_algo - Hash algorithm
15449 * @param {Uint8Array} data - Message
15450 * @param {Uint8Array} n - RSA public modulus
15451 * @param {Uint8Array} e - RSA public exponent
15452 * @param {Uint8Array} d - RSA private exponent
15453 * @param {Uint8Array} p - RSA private prime p
15454 * @param {Uint8Array} q - RSA private prime q
15455 * @param {Uint8Array} u - RSA private coefficient
15456 * @param {Uint8Array} hashed - Hashed message
15457 * @returns {Uint8Array} RSA Signature.
15458 * @async
15459 */
15460async function sign(hash_algo, data, n, e, d, p, q, u, hashed) {
15461 if (data && !util.isStream(data)) {
15462 if (util.getWebCrypto()) {
15463 try {
15464 return await webSign(enums.read(enums.webHash, hash_algo), data, n, e, d, p, q, u);
15465 } catch (err) {
15466 util.printDebugError(err);
15467 }
15468 } else if (util.getNodeCrypto()) {
15469 return nodeSign(hash_algo, data, n, e, d, p, q, u);
15470 }
15471 }
15472 return bnSign(hash_algo, n, d, hashed);
15473}
15474
15475/**
15476 * Verify signature
15477 * @param {module:enums.hash} hash_algo - Hash algorithm
15478 * @param {Uint8Array} data - Message
15479 * @param {Uint8Array} s - Signature
15480 * @param {Uint8Array} n - RSA public modulus
15481 * @param {Uint8Array} e - RSA public exponent
15482 * @param {Uint8Array} hashed - Hashed message
15483 * @returns {Boolean}
15484 * @async
15485 */
15486async function verify(hash_algo, data, s, n, e, hashed) {
15487 if (data && !util.isStream(data)) {
15488 if (util.getWebCrypto()) {
15489 try {
15490 return await webVerify(enums.read(enums.webHash, hash_algo), data, s, n, e);
15491 } catch (err) {
15492 util.printDebugError(err);
15493 }
15494 } else if (util.getNodeCrypto()) {
15495 return nodeVerify(hash_algo, data, s, n, e);
15496 }
15497 }
15498 return bnVerify(hash_algo, s, n, e, hashed);
15499}
15500
15501/**
15502 * Encrypt message
15503 * @param {Uint8Array} data - Message
15504 * @param {Uint8Array} n - RSA public modulus
15505 * @param {Uint8Array} e - RSA public exponent
15506 * @returns {Uint8Array} RSA Ciphertext.
15507 * @async
15508 */
15509async function encrypt$1(data, n, e) {
15510 if (util.getNodeCrypto()) {
15511 return nodeEncrypt$1(data, n, e);
15512 }
15513 return bnEncrypt(data, n, e);
15514}
15515
15516/**
15517 * Decrypt RSA message
15518 * @param {Uint8Array} m - Message
15519 * @param {Uint8Array} n - RSA public modulus
15520 * @param {Uint8Array} e - RSA public exponent
15521 * @param {Uint8Array} d - RSA private exponent
15522 * @param {Uint8Array} p - RSA private prime p
15523 * @param {Uint8Array} q - RSA private prime q
15524 * @param {Uint8Array} u - RSA private coefficient
15525 * @returns {String} RSA Plaintext.
15526 * @async
15527 */
15528async function decrypt$1(data, n, e, d, p, q, u) {
15529 if (util.getNodeCrypto()) {
15530 return nodeDecrypt$1(data, n, e, d, p, q, u);
15531 }
15532 return bnDecrypt(data, n, e, d, p, q, u);
15533}
15534
15535/**
15536 * Generate a new random private key B bits long with public exponent E.
15537 *
15538 * When possible, webCrypto or nodeCrypto is used. Otherwise, primes are generated using
15539 * 40 rounds of the Miller-Rabin probabilistic random prime generation algorithm.
15540 * @see module:crypto/public_key/prime
15541 * @param {Integer} bits - RSA bit length
15542 * @param {Integer} e - RSA public exponent
15543 * @returns {{n, e, d,
15544 * p, q ,u: Uint8Array}} RSA public modulus, RSA public exponent, RSA private exponent,
15545 * RSA private prime p, RSA private prime q, u = p ** -1 mod q
15546 * @async
15547 */
15548async function generate(bits, e) {
15549 const BigInteger = await util.getBigInteger();
15550
15551 e = new BigInteger(e);
15552
15553 // Native RSA keygen using Web Crypto
15554 if (util.getWebCrypto()) {
15555 let keyPair;
15556 let keyGenOpt;
15557 if ((globalThis.crypto && globalThis.crypto.subtle) || globalThis.msCrypto) {
15558 // current standard spec
15559 keyGenOpt = {
15560 name: 'RSASSA-PKCS1-v1_5',
15561 modulusLength: bits, // the specified keysize in bits
15562 publicExponent: e.toUint8Array(), // take three bytes (max 65537) for exponent
15563 hash: {
15564 name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
15565 }
15566 };
15567 keyPair = webCrypto$5.generateKey(keyGenOpt, true, ['sign', 'verify']);
15568 keyPair = await promisifyIE11Op(keyPair, 'Error generating RSA key pair.');
15569 } else if (globalThis.crypto && globalThis.crypto.webkitSubtle) {
15570 // outdated spec implemented by old Webkit
15571 keyGenOpt = {
15572 name: 'RSA-OAEP',
15573 modulusLength: bits, // the specified keysize in bits
15574 publicExponent: e.toUint8Array(), // take three bytes (max 65537) for exponent
15575 hash: {
15576 name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
15577 }
15578 };
15579 keyPair = await webCrypto$5.generateKey(keyGenOpt, true, ['encrypt', 'decrypt']);
15580 } else {
15581 throw new Error('Unknown WebCrypto implementation');
15582 }
15583
15584 // export the generated keys as JsonWebKey (JWK)
15585 // https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
15586 let jwk = webCrypto$5.exportKey('jwk', keyPair.privateKey);
15587 jwk = await promisifyIE11Op(jwk, 'Error exporting RSA key pair.');
15588
15589 // parse raw ArrayBuffer bytes to jwk/json (WebKit/Safari/IE11 quirk)
15590 if (jwk instanceof ArrayBuffer) {
15591 jwk = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(jwk)));
15592 }
15593 // map JWK parameters to corresponding OpenPGP names
15594 return {
15595 n: b64ToUint8Array(jwk.n),
15596 e: e.toUint8Array(),
15597 d: b64ToUint8Array(jwk.d),
15598 // switch p and q
15599 p: b64ToUint8Array(jwk.q),
15600 q: b64ToUint8Array(jwk.p),
15601 // Since p and q are switched in places, u is the inverse of jwk.q
15602 u: b64ToUint8Array(jwk.qi)
15603 };
15604 } else if (util.getNodeCrypto() && nodeCrypto$6.generateKeyPair && RSAPrivateKey) {
15605 const opts = {
15606 modulusLength: bits,
15607 publicExponent: e.toNumber(),
15608 publicKeyEncoding: { type: 'pkcs1', format: 'der' },
15609 privateKeyEncoding: { type: 'pkcs1', format: 'der' }
15610 };
15611 const prv = await new Promise((resolve, reject) => nodeCrypto$6.generateKeyPair('rsa', opts, (err, _, der) => {
15612 if (err) {
15613 reject(err);
15614 } else {
15615 resolve(RSAPrivateKey.decode(der, 'der'));
15616 }
15617 }));
15618 /**
15619 * OpenPGP spec differs from DER spec, DER: `u = (inverse of q) mod p`, OpenPGP: `u = (inverse of p) mod q`.
15620 * @link https://tools.ietf.org/html/rfc3447#section-3.2
15621 * @link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-08#section-5.6.1
15622 */
15623 return {
15624 n: prv.modulus.toArrayLike(Uint8Array),
15625 e: prv.publicExponent.toArrayLike(Uint8Array),
15626 d: prv.privateExponent.toArrayLike(Uint8Array),
15627 // switch p and q
15628 p: prv.prime2.toArrayLike(Uint8Array),
15629 q: prv.prime1.toArrayLike(Uint8Array),
15630 // Since p and q are switched in places, we can keep u as defined by DER
15631 u: prv.coefficient.toArrayLike(Uint8Array)
15632 };
15633 }
15634
15635 // RSA keygen fallback using 40 iterations of the Miller-Rabin test
15636 // See https://stackoverflow.com/a/6330138 for justification
15637 // Also see section C.3 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST
15638 let q = await randomProbablePrime(bits - (bits >> 1), e, 40);
15639 let p = await randomProbablePrime(bits >> 1, e, 40);
15640
15641 if (q.lt(p)) {
15642 [p, q] = [q, p];
15643 }
15644 const phi = p.dec().imul(q.dec());
15645 return {
15646 n: p.mul(q).toUint8Array(),
15647 e: e.toUint8Array(),
15648 d: e.modInv(phi).toUint8Array(),
15649 p: p.toUint8Array(),
15650 q: q.toUint8Array(),
15651 // dp: d.mod(p.subn(1)),
15652 // dq: d.mod(q.subn(1)),
15653 u: p.modInv(q).toUint8Array()
15654 };
15655}
15656
15657/**
15658 * Validate RSA parameters
15659 * @param {Uint8Array} n - RSA public modulus
15660 * @param {Uint8Array} e - RSA public exponent
15661 * @param {Uint8Array} d - RSA private exponent
15662 * @param {Uint8Array} p - RSA private prime p
15663 * @param {Uint8Array} q - RSA private prime q
15664 * @param {Uint8Array} u - RSA inverse of p w.r.t. q
15665 * @returns {Boolean} Whether params are valid.
15666 * @async
15667 */
15668async function validateParams(n, e, d, p, q, u) {
15669 const BigInteger = await util.getBigInteger();
15670 n = new BigInteger(n);
15671 p = new BigInteger(p);
15672 q = new BigInteger(q);
15673
15674 // expect pq = n
15675 if (!p.mul(q).equal(n)) {
15676 return false;
15677 }
15678
15679 const two = new BigInteger(2);
15680 // expect p*u = 1 mod q
15681 u = new BigInteger(u);
15682 if (!p.mul(u).mod(q).isOne()) {
15683 return false;
15684 }
15685
15686 e = new BigInteger(e);
15687 d = new BigInteger(d);
15688 /**
15689 * In RSA pkcs#1 the exponents (d, e) are inverses modulo lcm(p-1, q-1)
15690 * We check that [de = 1 mod (p-1)] and [de = 1 mod (q-1)]
15691 * By CRT on coprime factors of (p-1, q-1) it follows that [de = 1 mod lcm(p-1, q-1)]
15692 *
15693 * We blind the multiplication with r, and check that rde = r mod lcm(p-1, q-1)
15694 */
15695 const nSizeOver3 = new BigInteger(Math.floor(n.bitLength() / 3));
15696 const r = await getRandomBigInteger(two, two.leftShift(nSizeOver3)); // r in [ 2, 2^{|n|/3} ) < p and q
15697 const rde = r.mul(d).mul(e);
15698
15699 const areInverses = rde.mod(p.dec()).equal(r) && rde.mod(q.dec()).equal(r);
15700 if (!areInverses) {
15701 return false;
15702 }
15703
15704 return true;
15705}
15706
15707async function bnSign(hash_algo, n, d, hashed) {
15708 const BigInteger = await util.getBigInteger();
15709 n = new BigInteger(n);
15710 const m = new BigInteger(await emsaEncode(hash_algo, hashed, n.byteLength()));
15711 d = new BigInteger(d);
15712 if (m.gte(n)) {
15713 throw new Error('Message size cannot exceed modulus size');
15714 }
15715 return m.modExp(d, n).toUint8Array('be', n.byteLength());
15716}
15717
15718async function webSign(hash_name, data, n, e, d, p, q, u) {
15719 /** OpenPGP keys require that p < q, and Safari Web Crypto requires that p > q.
15720 * We swap them in privateToJwk, so it usually works out, but nevertheless,
15721 * not all OpenPGP keys are compatible with this requirement.
15722 * OpenPGP.js used to generate RSA keys the wrong way around (p > q), and still
15723 * does if the underlying Web Crypto does so (e.g. old MS Edge 50% of the time).
15724 */
15725 const jwk = await privateToJwk(n, e, d, p, q, u);
15726 const algo = {
15727 name: "RSASSA-PKCS1-v1_5",
15728 hash: { name: hash_name }
15729 };
15730 const key = await webCrypto$5.importKey("jwk", jwk, algo, false, ["sign"]);
15731 // add hash field for ms edge support
15732 return new Uint8Array(await webCrypto$5.sign({ "name": "RSASSA-PKCS1-v1_5", "hash": hash_name }, key, data));
15733}
15734
15735async function nodeSign(hash_algo, data, n, e, d, p, q, u) {
15736 const { default: BN } = await import('./bn.mjs');
15737 const pBNum = new BN(p);
15738 const qBNum = new BN(q);
15739 const dBNum = new BN(d);
15740 const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1)
15741 const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1)
15742 const sign = nodeCrypto$6.createSign(enums.read(enums.hash, hash_algo));
15743 sign.write(data);
15744 sign.end();
15745 const keyObject = {
15746 version: 0,
15747 modulus: new BN(n),
15748 publicExponent: new BN(e),
15749 privateExponent: new BN(d),
15750 // switch p and q
15751 prime1: new BN(q),
15752 prime2: new BN(p),
15753 // switch dp and dq
15754 exponent1: dq,
15755 exponent2: dp,
15756 coefficient: new BN(u)
15757 };
15758 if (typeof nodeCrypto$6.createPrivateKey !== 'undefined') { //from version 11.6.0 Node supports der encoded key objects
15759 const der = RSAPrivateKey.encode(keyObject, 'der');
15760 return new Uint8Array(sign.sign({ key: der, format: 'der', type: 'pkcs1' }));
15761 }
15762 const pem = RSAPrivateKey.encode(keyObject, 'pem', {
15763 label: 'RSA PRIVATE KEY'
15764 });
15765 return new Uint8Array(sign.sign(pem));
15766}
15767
15768async function bnVerify(hash_algo, s, n, e, hashed) {
15769 const BigInteger = await util.getBigInteger();
15770 n = new BigInteger(n);
15771 s = new BigInteger(s);
15772 e = new BigInteger(e);
15773 if (s.gte(n)) {
15774 throw new Error('Signature size cannot exceed modulus size');
15775 }
15776 const EM1 = s.modExp(e, n).toUint8Array('be', n.byteLength());
15777 const EM2 = await emsaEncode(hash_algo, hashed, n.byteLength());
15778 return util.equalsUint8Array(EM1, EM2);
15779}
15780
15781async function webVerify(hash_name, data, s, n, e) {
15782 const jwk = publicToJwk(n, e);
15783 const key = await webCrypto$5.importKey("jwk", jwk, {
15784 name: "RSASSA-PKCS1-v1_5",
15785 hash: { name: hash_name }
15786 }, false, ["verify"]);
15787 // add hash field for ms edge support
15788 return webCrypto$5.verify({ "name": "RSASSA-PKCS1-v1_5", "hash": hash_name }, key, s, data);
15789}
15790
15791async function nodeVerify(hash_algo, data, s, n, e) {
15792 const { default: BN } = await import('./bn.mjs');
15793
15794 const verify = nodeCrypto$6.createVerify(enums.read(enums.hash, hash_algo));
15795 verify.write(data);
15796 verify.end();
15797 const keyObject = {
15798 modulus: new BN(n),
15799 publicExponent: new BN(e)
15800 };
15801 let key;
15802 if (typeof nodeCrypto$6.createPrivateKey !== 'undefined') { //from version 11.6.0 Node supports der encoded key objects
15803 const der = RSAPublicKey.encode(keyObject, 'der');
15804 key = { key: der, format: 'der', type: 'pkcs1' };
15805 } else {
15806 key = RSAPublicKey.encode(keyObject, 'pem', {
15807 label: 'RSA PUBLIC KEY'
15808 });
15809 }
15810 try {
15811 return await verify.verify(key, s);
15812 } catch (err) {
15813 return false;
15814 }
15815}
15816
15817async function nodeEncrypt$1(data, n, e) {
15818 const { default: BN } = await import('./bn.mjs');
15819
15820 const keyObject = {
15821 modulus: new BN(n),
15822 publicExponent: new BN(e)
15823 };
15824 let key;
15825 if (typeof nodeCrypto$6.createPrivateKey !== 'undefined') {
15826 const der = RSAPublicKey.encode(keyObject, 'der');
15827 key = { key: der, format: 'der', type: 'pkcs1', padding: nodeCrypto$6.constants.RSA_PKCS1_PADDING };
15828 } else {
15829 const pem = RSAPublicKey.encode(keyObject, 'pem', {
15830 label: 'RSA PUBLIC KEY'
15831 });
15832 key = { key: pem, padding: nodeCrypto$6.constants.RSA_PKCS1_PADDING };
15833 }
15834 return new Uint8Array(nodeCrypto$6.publicEncrypt(key, data));
15835}
15836
15837async function bnEncrypt(data, n, e) {
15838 const BigInteger = await util.getBigInteger();
15839 n = new BigInteger(n);
15840 data = new BigInteger(await emeEncode(data, n.byteLength()));
15841 e = new BigInteger(e);
15842 if (data.gte(n)) {
15843 throw new Error('Message size cannot exceed modulus size');
15844 }
15845 return data.modExp(e, n).toUint8Array('be', n.byteLength());
15846}
15847
15848async function nodeDecrypt$1(data, n, e, d, p, q, u) {
15849 const { default: BN } = await import('./bn.mjs');
15850
15851 const pBNum = new BN(p);
15852 const qBNum = new BN(q);
15853 const dBNum = new BN(d);
15854 const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1)
15855 const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1)
15856 const keyObject = {
15857 version: 0,
15858 modulus: new BN(n),
15859 publicExponent: new BN(e),
15860 privateExponent: new BN(d),
15861 // switch p and q
15862 prime1: new BN(q),
15863 prime2: new BN(p),
15864 // switch dp and dq
15865 exponent1: dq,
15866 exponent2: dp,
15867 coefficient: new BN(u)
15868 };
15869 let key;
15870 if (typeof nodeCrypto$6.createPrivateKey !== 'undefined') {
15871 const der = RSAPrivateKey.encode(keyObject, 'der');
15872 key = { key: der, format: 'der' , type: 'pkcs1', padding: nodeCrypto$6.constants.RSA_PKCS1_PADDING };
15873 } else {
15874 const pem = RSAPrivateKey.encode(keyObject, 'pem', {
15875 label: 'RSA PRIVATE KEY'
15876 });
15877 key = { key: pem, padding: nodeCrypto$6.constants.RSA_PKCS1_PADDING };
15878 }
15879 try {
15880 return new Uint8Array(nodeCrypto$6.privateDecrypt(key, data));
15881 } catch (err) {
15882 throw new Error('Decryption error');
15883 }
15884}
15885
15886async function bnDecrypt(data, n, e, d, p, q, u) {
15887 const BigInteger = await util.getBigInteger();
15888 data = new BigInteger(data);
15889 n = new BigInteger(n);
15890 e = new BigInteger(e);
15891 d = new BigInteger(d);
15892 p = new BigInteger(p);
15893 q = new BigInteger(q);
15894 u = new BigInteger(u);
15895 if (data.gte(n)) {
15896 throw new Error('Data too large.');
15897 }
15898 const dq = d.mod(q.dec()); // d mod (q-1)
15899 const dp = d.mod(p.dec()); // d mod (p-1)
15900
15901 const unblinder = (await getRandomBigInteger(new BigInteger(2), n)).mod(n);
15902 const blinder = unblinder.modInv(n).modExp(e, n);
15903 data = data.mul(blinder).mod(n);
15904
15905
15906 const mp = data.modExp(dp, p); // data**{d mod (q-1)} mod p
15907 const mq = data.modExp(dq, q); // data**{d mod (p-1)} mod q
15908 const h = u.mul(mq.sub(mp)).mod(q); // u * (mq-mp) mod q (operands already < q)
15909
15910 let result = h.mul(p).add(mp); // result < n due to relations above
15911
15912 result = result.mul(unblinder).mod(n);
15913
15914
15915 return emeDecode(result.toUint8Array('be', n.byteLength()));
15916}
15917
15918/** Convert Openpgp private key params to jwk key according to
15919 * @link https://tools.ietf.org/html/rfc7517
15920 * @param {String} hash_algo
15921 * @param {Uint8Array} n
15922 * @param {Uint8Array} e
15923 * @param {Uint8Array} d
15924 * @param {Uint8Array} p
15925 * @param {Uint8Array} q
15926 * @param {Uint8Array} u
15927 */
15928async function privateToJwk(n, e, d, p, q, u) {
15929 const BigInteger = await util.getBigInteger();
15930 const pNum = new BigInteger(p);
15931 const qNum = new BigInteger(q);
15932 const dNum = new BigInteger(d);
15933
15934 let dq = dNum.mod(qNum.dec()); // d mod (q-1)
15935 let dp = dNum.mod(pNum.dec()); // d mod (p-1)
15936 dp = dp.toUint8Array();
15937 dq = dq.toUint8Array();
15938 return {
15939 kty: 'RSA',
15940 n: uint8ArrayToB64(n, true),
15941 e: uint8ArrayToB64(e, true),
15942 d: uint8ArrayToB64(d, true),
15943 // switch p and q
15944 p: uint8ArrayToB64(q, true),
15945 q: uint8ArrayToB64(p, true),
15946 // switch dp and dq
15947 dp: uint8ArrayToB64(dq, true),
15948 dq: uint8ArrayToB64(dp, true),
15949 qi: uint8ArrayToB64(u, true),
15950 ext: true
15951 };
15952}
15953
15954/** Convert Openpgp key public params to jwk key according to
15955 * @link https://tools.ietf.org/html/rfc7517
15956 * @param {String} hash_algo
15957 * @param {Uint8Array} n
15958 * @param {Uint8Array} e
15959 */
15960function publicToJwk(n, e) {
15961 return {
15962 kty: 'RSA',
15963 n: uint8ArrayToB64(n, true),
15964 e: uint8ArrayToB64(e, true),
15965 ext: true
15966 };
15967}
15968
15969var rsa = /*#__PURE__*/Object.freeze({
15970 __proto__: null,
15971 sign: sign,
15972 verify: verify,
15973 encrypt: encrypt$1,
15974 decrypt: decrypt$1,
15975 generate: generate,
15976 validateParams: validateParams
15977});
15978
15979// GPG4Browsers - An OpenPGP implementation in javascript
15980
15981/**
15982 * ElGamal Encryption function
15983 * Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)
15984 * @param {Uint8Array} data - To be padded and encrypted
15985 * @param {Uint8Array} p
15986 * @param {Uint8Array} g
15987 * @param {Uint8Array} y
15988 * @returns {{ c1: Uint8Array, c2: Uint8Array }}
15989 * @async
15990 */
15991async function encrypt$2(data, p, g, y) {
15992 const BigInteger = await util.getBigInteger();
15993 p = new BigInteger(p);
15994 g = new BigInteger(g);
15995 y = new BigInteger(y);
15996
15997 const padded = await emeEncode(data, p.byteLength());
15998 const m = new BigInteger(padded);
15999
16000 // OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ*
16001 // hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2]
16002 const k = await getRandomBigInteger(new BigInteger(1), p.dec());
16003 return {
16004 c1: g.modExp(k, p).toUint8Array(),
16005 c2: y.modExp(k, p).imul(m).imod(p).toUint8Array()
16006 };
16007}
16008
16009/**
16010 * ElGamal Encryption function
16011 * @param {Uint8Array} c1
16012 * @param {Uint8Array} c2
16013 * @param {Uint8Array} p
16014 * @param {Uint8Array} x
16015 * @returns {Uint8Array} Unpadded message.
16016 * @async
16017 */
16018async function decrypt$2(c1, c2, p, x) {
16019 const BigInteger = await util.getBigInteger();
16020 c1 = new BigInteger(c1);
16021 c2 = new BigInteger(c2);
16022 p = new BigInteger(p);
16023 x = new BigInteger(x);
16024
16025 const padded = c1.modExp(x, p).modInv(p).imul(c2).imod(p);
16026 return emeDecode(padded.toUint8Array('be', p.byteLength()));
16027}
16028
16029/**
16030 * Validate ElGamal parameters
16031 * @param {Uint8Array} p - ElGamal prime
16032 * @param {Uint8Array} g - ElGamal group generator
16033 * @param {Uint8Array} y - ElGamal public key
16034 * @param {Uint8Array} x - ElGamal private exponent
16035 * @returns {Boolean} Whether params are valid.
16036 * @async
16037 */
16038async function validateParams$1(p, g, y, x) {
16039 const BigInteger = await util.getBigInteger();
16040 p = new BigInteger(p);
16041 g = new BigInteger(g);
16042 y = new BigInteger(y);
16043
16044 const one = new BigInteger(1);
16045 // Check that 1 < g < p
16046 if (g.lte(one) || g.gte(p)) {
16047 return false;
16048 }
16049
16050 // Expect p-1 to be large
16051 const pSize = new BigInteger(p.bitLength());
16052 const n1023 = new BigInteger(1023);
16053 if (pSize.lt(n1023)) {
16054 return false;
16055 }
16056
16057 /**
16058 * g should have order p-1
16059 * Check that g ** (p-1) = 1 mod p
16060 */
16061 if (!g.modExp(p.dec(), p).isOne()) {
16062 return false;
16063 }
16064
16065 /**
16066 * Since p-1 is not prime, g might have a smaller order that divides p-1
16067 * We want to make sure that the order is large enough to hinder a small subgroup attack
16068 *
16069 * We just check g**i != 1 for all i up to a threshold
16070 */
16071 let res = g;
16072 const i = new BigInteger(1);
16073 const threshold = new BigInteger(2).leftShift(new BigInteger(17)); // we want order > threshold
16074 while (i.lt(threshold)) {
16075 res = res.mul(g).imod(p);
16076 if (res.isOne()) {
16077 return false;
16078 }
16079 i.iinc();
16080 }
16081
16082 /**
16083 * Re-derive public key y' = g ** x mod p
16084 * Expect y == y'
16085 *
16086 * Blinded exponentiation computes g**{r(p-1) + x} to compare to y
16087 */
16088 x = new BigInteger(x);
16089 const two = new BigInteger(2);
16090 const r = await getRandomBigInteger(two.leftShift(pSize.dec()), two.leftShift(pSize)); // draw r of same size as p-1
16091 const rqx = p.dec().imul(r).iadd(x);
16092 if (!y.equal(g.modExp(rqx, p))) {
16093 return false;
16094 }
16095
16096 return true;
16097}
16098
16099var elgamal = /*#__PURE__*/Object.freeze({
16100 __proto__: null,
16101 encrypt: encrypt$2,
16102 decrypt: decrypt$2,
16103 validateParams: validateParams$1
16104});
16105
16106// OpenPGP.js - An OpenPGP implementation in javascript
16107
16108class OID {
16109 constructor(oid) {
16110 if (oid instanceof OID) {
16111 this.oid = oid.oid;
16112 } else if (util.isArray(oid) ||
16113 util.isUint8Array(oid)) {
16114 oid = new Uint8Array(oid);
16115 if (oid[0] === 0x06) { // DER encoded oid byte array
16116 if (oid[1] !== oid.length - 2) {
16117 throw new Error('Length mismatch in DER encoded oid');
16118 }
16119 oid = oid.subarray(2);
16120 }
16121 this.oid = oid;
16122 } else {
16123 this.oid = '';
16124 }
16125 }
16126
16127 /**
16128 * Method to read an OID object
16129 * @param {Uint8Array} input - Where to read the OID from
16130 * @returns {Number} Number of read bytes.
16131 */
16132 read(input) {
16133 if (input.length >= 1) {
16134 const length = input[0];
16135 if (input.length >= 1 + length) {
16136 this.oid = input.subarray(1, 1 + length);
16137 return 1 + this.oid.length;
16138 }
16139 }
16140 throw new Error('Invalid oid');
16141 }
16142
16143 /**
16144 * Serialize an OID object
16145 * @returns {Uint8Array} Array with the serialized value the OID.
16146 */
16147 write() {
16148 return util.concatUint8Array([new Uint8Array([this.oid.length]), this.oid]);
16149 }
16150
16151 /**
16152 * Serialize an OID object as a hex string
16153 * @returns {string} String with the hex value of the OID.
16154 */
16155 toHex() {
16156 return util.uint8ArrayToHex(this.oid);
16157 }
16158
16159 /**
16160 * If a known curve object identifier, return the canonical name of the curve
16161 * @returns {string} String with the canonical name of the curve.
16162 */
16163 getName() {
16164 const hex = this.toHex();
16165 if (enums.curve[hex]) {
16166 return enums.write(enums.curve, hex);
16167 } else {
16168 throw new Error('Unknown curve object identifier.');
16169 }
16170 }
16171}
16172
16173// OpenPGP.js - An OpenPGP implementation in javascript
16174
16175function keyFromPrivate(indutnyCurve, priv) {
16176 const keyPair = indutnyCurve.keyPair({ priv: priv });
16177 return keyPair;
16178}
16179
16180function keyFromPublic(indutnyCurve, pub) {
16181 const keyPair = indutnyCurve.keyPair({ pub: pub });
16182 if (keyPair.validate().result !== true) {
16183 throw new Error('Invalid elliptic public key');
16184 }
16185 return keyPair;
16186}
16187
16188async function getIndutnyCurve(name) {
16189 if (!defaultConfig.useIndutnyElliptic) {
16190 throw new Error('This curve is only supported in the full build of OpenPGP.js');
16191 }
16192 const { default: elliptic } = await import('./elliptic.mjs');
16193 return new elliptic.ec(name);
16194}
16195
16196// OpenPGP.js - An OpenPGP implementation in javascript
16197
16198const webCrypto$6 = util.getWebCrypto();
16199const nodeCrypto$7 = util.getNodeCrypto();
16200
16201const webCurves = {
16202 'p256': 'P-256',
16203 'p384': 'P-384',
16204 'p521': 'P-521'
16205};
16206const knownCurves = nodeCrypto$7 ? nodeCrypto$7.getCurves() : [];
16207const nodeCurves = nodeCrypto$7 ? {
16208 secp256k1: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined,
16209 p256: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined,
16210 p384: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined,
16211 p521: knownCurves.includes('secp521r1') ? 'secp521r1' : undefined,
16212 ed25519: knownCurves.includes('ED25519') ? 'ED25519' : undefined,
16213 curve25519: knownCurves.includes('X25519') ? 'X25519' : undefined,
16214 brainpoolP256r1: knownCurves.includes('brainpoolP256r1') ? 'brainpoolP256r1' : undefined,
16215 brainpoolP384r1: knownCurves.includes('brainpoolP384r1') ? 'brainpoolP384r1' : undefined,
16216 brainpoolP512r1: knownCurves.includes('brainpoolP512r1') ? 'brainpoolP512r1' : undefined
16217} : {};
16218
16219const curves = {
16220 p256: {
16221 oid: [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07],
16222 keyType: enums.publicKey.ecdsa,
16223 hash: enums.hash.sha256,
16224 cipher: enums.symmetric.aes128,
16225 node: nodeCurves.p256,
16226 web: webCurves.p256,
16227 payloadSize: 32,
16228 sharedSize: 256
16229 },
16230 p384: {
16231 oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22],
16232 keyType: enums.publicKey.ecdsa,
16233 hash: enums.hash.sha384,
16234 cipher: enums.symmetric.aes192,
16235 node: nodeCurves.p384,
16236 web: webCurves.p384,
16237 payloadSize: 48,
16238 sharedSize: 384
16239 },
16240 p521: {
16241 oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23],
16242 keyType: enums.publicKey.ecdsa,
16243 hash: enums.hash.sha512,
16244 cipher: enums.symmetric.aes256,
16245 node: nodeCurves.p521,
16246 web: webCurves.p521,
16247 payloadSize: 66,
16248 sharedSize: 528
16249 },
16250 secp256k1: {
16251 oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A],
16252 keyType: enums.publicKey.ecdsa,
16253 hash: enums.hash.sha256,
16254 cipher: enums.symmetric.aes128,
16255 node: nodeCurves.secp256k1,
16256 payloadSize: 32
16257 },
16258 ed25519: {
16259 oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
16260 keyType: enums.publicKey.eddsa,
16261 hash: enums.hash.sha512,
16262 node: false, // nodeCurves.ed25519 TODO
16263 payloadSize: 32
16264 },
16265 curve25519: {
16266 oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01],
16267 keyType: enums.publicKey.ecdh,
16268 hash: enums.hash.sha256,
16269 cipher: enums.symmetric.aes128,
16270 node: false, // nodeCurves.curve25519 TODO
16271 payloadSize: 32
16272 },
16273 brainpoolP256r1: {
16274 oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07],
16275 keyType: enums.publicKey.ecdsa,
16276 hash: enums.hash.sha256,
16277 cipher: enums.symmetric.aes128,
16278 node: nodeCurves.brainpoolP256r1,
16279 payloadSize: 32
16280 },
16281 brainpoolP384r1: {
16282 oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B],
16283 keyType: enums.publicKey.ecdsa,
16284 hash: enums.hash.sha384,
16285 cipher: enums.symmetric.aes192,
16286 node: nodeCurves.brainpoolP384r1,
16287 payloadSize: 48
16288 },
16289 brainpoolP512r1: {
16290 oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D],
16291 keyType: enums.publicKey.ecdsa,
16292 hash: enums.hash.sha512,
16293 cipher: enums.symmetric.aes256,
16294 node: nodeCurves.brainpoolP512r1,
16295 payloadSize: 64
16296 }
16297};
16298
16299class Curve {
16300 constructor(oid_or_name, params) {
16301 try {
16302 if (util.isArray(oid_or_name) ||
16303 util.isUint8Array(oid_or_name)) {
16304 // by oid byte array
16305 oid_or_name = new OID(oid_or_name);
16306 }
16307 if (oid_or_name instanceof OID) {
16308 // by curve OID
16309 oid_or_name = oid_or_name.getName();
16310 }
16311 // by curve name or oid string
16312 this.name = enums.write(enums.curve, oid_or_name);
16313 } catch (err) {
16314 throw new Error('Not valid curve');
16315 }
16316 params = params || curves[this.name];
16317
16318 this.keyType = params.keyType;
16319
16320 this.oid = params.oid;
16321 this.hash = params.hash;
16322 this.cipher = params.cipher;
16323 this.node = params.node && curves[this.name];
16324 this.web = params.web && curves[this.name];
16325 this.payloadSize = params.payloadSize;
16326 if (this.web && util.getWebCrypto()) {
16327 this.type = 'web';
16328 } else if (this.node && util.getNodeCrypto()) {
16329 this.type = 'node';
16330 } else if (this.name === 'curve25519') {
16331 this.type = 'curve25519';
16332 } else if (this.name === 'ed25519') {
16333 this.type = 'ed25519';
16334 }
16335 }
16336
16337 async genKeyPair() {
16338 let keyPair;
16339 switch (this.type) {
16340 case 'web':
16341 try {
16342 return await webGenKeyPair(this.name);
16343 } catch (err) {
16344 util.printDebugError("Browser did not support generating ec key " + err.message);
16345 break;
16346 }
16347 case 'node':
16348 return nodeGenKeyPair(this.name);
16349 case 'curve25519': {
16350 const privateKey = await getRandomBytes(32);
16351 privateKey[0] = (privateKey[0] & 127) | 64;
16352 privateKey[31] &= 248;
16353 const secretKey = privateKey.slice().reverse();
16354 keyPair = naclFastLight.box.keyPair.fromSecretKey(secretKey);
16355 const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]);
16356 return { publicKey, privateKey };
16357 }
16358 case 'ed25519': {
16359 const privateKey = await getRandomBytes(32);
16360 const keyPair = naclFastLight.sign.keyPair.fromSeed(privateKey);
16361 const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]);
16362 return { publicKey, privateKey };
16363 }
16364 }
16365 const indutnyCurve = await getIndutnyCurve(this.name);
16366 keyPair = await indutnyCurve.genKeyPair({
16367 entropy: util.uint8ArrayToStr(await getRandomBytes(32))
16368 });
16369 return { publicKey: new Uint8Array(keyPair.getPublic('array', false)), privateKey: keyPair.getPrivate().toArrayLike(Uint8Array) };
16370 }
16371}
16372
16373async function generate$1(curve) {
16374 const BigInteger = await util.getBigInteger();
16375
16376 curve = new Curve(curve);
16377 const keyPair = await curve.genKeyPair();
16378 const Q = new BigInteger(keyPair.publicKey).toUint8Array();
16379 const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize);
16380 return {
16381 oid: curve.oid,
16382 Q,
16383 secret,
16384 hash: curve.hash,
16385 cipher: curve.cipher
16386 };
16387}
16388
16389function getPreferredHashAlgo(oid) {
16390 return curves[enums.write(enums.curve, oid.toHex())].hash;
16391}
16392
16393/**
16394 * Validate ECDH and EcDSA parameters
16395 * Not suitable for EdDSA (different secret key format)
16396 * @param {module:enums.publicKey} algo - EC algorithm, to filter supported curves
16397 * @param {module:type/oid} oid - EC object identifier
16398 * @param {Uint8Array} Q - EC public point
16399 * @param {Uint8Array} d - EC secret scalar
16400 * @returns {Boolean} Whether params are valid.
16401 * @async
16402 */
16403async function validateStandardParams(algo, oid, Q, d) {
16404 const supportedCurves = {
16405 p256: true,
16406 p384: true,
16407 p521: true,
16408 secp256k1: true,
16409 curve25519: algo === enums.publicKey.ecdh,
16410 brainpoolP256r1: true,
16411 brainpoolP384r1: true,
16412 brainpoolP512r1: true
16413 };
16414
16415 // Check whether the given curve is supported
16416 const curveName = oid.getName();
16417 if (!supportedCurves[curveName]) {
16418 return false;
16419 }
16420
16421 if (curveName === 'curve25519') {
16422 d = d.slice().reverse();
16423 // Re-derive public point Q'
16424 const { publicKey } = naclFastLight.box.keyPair.fromSecretKey(d);
16425
16426 Q = new Uint8Array(Q);
16427 const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
16428 if (!util.equalsUint8Array(dG, Q)) {
16429 return false;
16430 }
16431
16432 return true;
16433 }
16434
16435 const curve = await getIndutnyCurve(curveName);
16436 try {
16437 // Parse Q and check that it is on the curve but not at infinity
16438 Q = keyFromPublic(curve, Q).getPublic();
16439 } catch (validationErrors) {
16440 return false;
16441 }
16442
16443 /**
16444 * Re-derive public point Q' = dG from private key
16445 * Expect Q == Q'
16446 */
16447 const dG = keyFromPrivate(curve, d).getPublic();
16448 if (!dG.eq(Q)) {
16449 return false;
16450 }
16451
16452 return true;
16453}
16454
16455//////////////////////////
16456// //
16457// Helper functions //
16458// //
16459//////////////////////////
16460
16461
16462async function webGenKeyPair(name) {
16463 // Note: keys generated with ECDSA and ECDH are structurally equivalent
16464 const webCryptoKey = await webCrypto$6.generateKey({ name: "ECDSA", namedCurve: webCurves[name] }, true, ["sign", "verify"]);
16465
16466 const privateKey = await webCrypto$6.exportKey("jwk", webCryptoKey.privateKey);
16467 const publicKey = await webCrypto$6.exportKey("jwk", webCryptoKey.publicKey);
16468
16469 return {
16470 publicKey: jwkToRawPublic(publicKey),
16471 privateKey: b64ToUint8Array(privateKey.d)
16472 };
16473}
16474
16475async function nodeGenKeyPair(name) {
16476 // Note: ECDSA and ECDH key generation is structurally equivalent
16477 const ecdh = nodeCrypto$7.createECDH(nodeCurves[name]);
16478 await ecdh.generateKeys();
16479 return {
16480 publicKey: new Uint8Array(ecdh.getPublicKey()),
16481 privateKey: new Uint8Array(ecdh.getPrivateKey())
16482 };
16483}
16484
16485//////////////////////////
16486// //
16487// Helper functions //
16488// //
16489//////////////////////////
16490
16491/**
16492 * @param {JsonWebKey} jwk - key for conversion
16493 *
16494 * @returns {Uint8Array} Raw public key.
16495 */
16496function jwkToRawPublic(jwk) {
16497 const bufX = b64ToUint8Array(jwk.x);
16498 const bufY = b64ToUint8Array(jwk.y);
16499 const publicKey = new Uint8Array(bufX.length + bufY.length + 1);
16500 publicKey[0] = 0x04;
16501 publicKey.set(bufX, 1);
16502 publicKey.set(bufY, bufX.length + 1);
16503 return publicKey;
16504}
16505
16506/**
16507 * @param {Integer} payloadSize - ec payload size
16508 * @param {String} name - curve name
16509 * @param {Uint8Array} publicKey - public key
16510 *
16511 * @returns {JsonWebKey} Public key in jwk format.
16512 */
16513function rawPublicToJwk(payloadSize, name, publicKey) {
16514 const len = payloadSize;
16515 const bufX = publicKey.slice(1, len + 1);
16516 const bufY = publicKey.slice(len + 1, len * 2 + 1);
16517 // https://www.rfc-editor.org/rfc/rfc7518.txt
16518 const jwk = {
16519 kty: "EC",
16520 crv: name,
16521 x: uint8ArrayToB64(bufX, true),
16522 y: uint8ArrayToB64(bufY, true),
16523 ext: true
16524 };
16525 return jwk;
16526}
16527
16528/**
16529 * @param {Integer} payloadSize - ec payload size
16530 * @param {String} name - curve name
16531 * @param {Uint8Array} publicKey - public key
16532 * @param {Uint8Array} privateKey - private key
16533 *
16534 * @returns {JsonWebKey} Private key in jwk format.
16535 */
16536function privateToJwk$1(payloadSize, name, publicKey, privateKey) {
16537 const jwk = rawPublicToJwk(payloadSize, name, publicKey);
16538 jwk.d = uint8ArrayToB64(privateKey, true);
16539 return jwk;
16540}
16541
16542// OpenPGP.js - An OpenPGP implementation in javascript
16543
16544const webCrypto$7 = util.getWebCrypto();
16545const nodeCrypto$8 = util.getNodeCrypto();
16546
16547/**
16548 * Sign a message using the provided key
16549 * @param {module:type/oid} oid - Elliptic curve object identifier
16550 * @param {module:enums.hash} hash_algo - Hash algorithm used to sign
16551 * @param {Uint8Array} message - Message to sign
16552 * @param {Uint8Array} publicKey - Public key
16553 * @param {Uint8Array} privateKey - Private key used to sign the message
16554 * @param {Uint8Array} hashed - The hashed message
16555 * @returns {{r: Uint8Array,
16556 * s: Uint8Array}} Signature of the message
16557 * @async
16558 */
16559async function sign$1(oid, hash_algo, message, publicKey, privateKey, hashed) {
16560 const curve = new Curve(oid);
16561 if (message && !util.isStream(message)) {
16562 const keyPair = { publicKey, privateKey };
16563 switch (curve.type) {
16564 case 'web': {
16565 // If browser doesn't support a curve, we'll catch it
16566 try {
16567 // Need to await to make sure browser succeeds
16568 return await webSign$1(curve, hash_algo, message, keyPair);
16569 } catch (err) {
16570 // We do not fallback if the error is related to key integrity
16571 // Unfortunaley Safari does not support p521 and throws a DataError when using it
16572 // So we need to always fallback for that curve
16573 if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) {
16574 throw err;
16575 }
16576 util.printDebugError("Browser did not support signing: " + err.message);
16577 }
16578 break;
16579 }
16580 case 'node': {
16581 const signature = await nodeSign$1(curve, hash_algo, message, keyPair);
16582 return {
16583 r: signature.r.toArrayLike(Uint8Array),
16584 s: signature.s.toArrayLike(Uint8Array)
16585 };
16586 }
16587 }
16588 }
16589 return ellipticSign(curve, hashed, privateKey);
16590}
16591
16592/**
16593 * Verifies if a signature is valid for a message
16594 * @param {module:type/oid} oid - Elliptic curve object identifier
16595 * @param {module:enums.hash} hash_algo - Hash algorithm used in the signature
16596 * @param {{r: Uint8Array,
16597 s: Uint8Array}} signature Signature to verify
16598 * @param {Uint8Array} message - Message to verify
16599 * @param {Uint8Array} publicKey - Public key used to verify the message
16600 * @param {Uint8Array} hashed - The hashed message
16601 * @returns {Boolean}
16602 * @async
16603 */
16604async function verify$1(oid, hash_algo, signature, message, publicKey, hashed) {
16605 const curve = new Curve(oid);
16606 if (message && !util.isStream(message)) {
16607 switch (curve.type) {
16608 case 'web':
16609 try {
16610 // Need to await to make sure browser succeeds
16611 return await webVerify$1(curve, hash_algo, signature, message, publicKey);
16612 } catch (err) {
16613 // We do not fallback if the error is related to key integrity
16614 // Unfortunately Safari does not support p521 and throws a DataError when using it
16615 // So we need to always fallback for that curve
16616 if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) {
16617 throw err;
16618 }
16619 util.printDebugError("Browser did not support verifying: " + err.message);
16620 }
16621 break;
16622 case 'node':
16623 return nodeVerify$1(curve, hash_algo, signature, message, publicKey);
16624 }
16625 }
16626 const digest = (typeof hash_algo === 'undefined') ? message : hashed;
16627 return ellipticVerify(curve, signature, digest, publicKey);
16628}
16629
16630/**
16631 * Validate EcDSA parameters
16632 * @param {module:type/oid} oid - Elliptic curve object identifier
16633 * @param {Uint8Array} Q - EcDSA public point
16634 * @param {Uint8Array} d - EcDSA secret scalar
16635 * @returns {Boolean} Whether params are valid.
16636 * @async
16637 */
16638async function validateParams$2(oid, Q, d) {
16639 const curve = new Curve(oid);
16640 // Reject curves x25519 and ed25519
16641 if (curve.keyType !== enums.publicKey.ecdsa) {
16642 return false;
16643 }
16644
16645 // To speed up the validation, we try to use node- or webcrypto when available
16646 // and sign + verify a random message
16647 switch (curve.type) {
16648 case 'web':
16649 case 'node': {
16650 const message = await getRandomBytes(8);
16651 const hashAlgo = enums.hash.sha256;
16652 const hashed = await hash.digest(hashAlgo, message);
16653 try {
16654 const signature = await sign$1(oid, hashAlgo, message, Q, d, hashed);
16655 return await verify$1(oid, hashAlgo, signature, message, Q, hashed);
16656 } catch (err) {
16657 return false;
16658 }
16659 }
16660 default:
16661 return validateStandardParams(enums.publicKey.ecdsa, oid, Q, d);
16662 }
16663}
16664
16665
16666//////////////////////////
16667// //
16668// Helper functions //
16669// //
16670//////////////////////////
16671
16672async function ellipticSign(curve, hashed, privateKey) {
16673 const indutnyCurve = await getIndutnyCurve(curve.name);
16674 const key = keyFromPrivate(indutnyCurve, privateKey);
16675 const signature = key.sign(hashed);
16676 return {
16677 r: signature.r.toArrayLike(Uint8Array),
16678 s: signature.s.toArrayLike(Uint8Array)
16679 };
16680}
16681
16682async function ellipticVerify(curve, signature, digest, publicKey) {
16683 const indutnyCurve = await getIndutnyCurve(curve.name);
16684 const key = keyFromPublic(indutnyCurve, publicKey);
16685 return key.verify(digest, signature);
16686}
16687
16688async function webSign$1(curve, hash_algo, message, keyPair) {
16689 const len = curve.payloadSize;
16690 const jwk = privateToJwk$1(curve.payloadSize, webCurves[curve.name], keyPair.publicKey, keyPair.privateKey);
16691 const key = await webCrypto$7.importKey(
16692 "jwk",
16693 jwk,
16694 {
16695 "name": "ECDSA",
16696 "namedCurve": webCurves[curve.name],
16697 "hash": { name: enums.read(enums.webHash, curve.hash) }
16698 },
16699 false,
16700 ["sign"]
16701 );
16702
16703 const signature = new Uint8Array(await webCrypto$7.sign(
16704 {
16705 "name": 'ECDSA',
16706 "namedCurve": webCurves[curve.name],
16707 "hash": { name: enums.read(enums.webHash, hash_algo) }
16708 },
16709 key,
16710 message
16711 ));
16712
16713 return {
16714 r: signature.slice(0, len),
16715 s: signature.slice(len, len << 1)
16716 };
16717}
16718
16719async function webVerify$1(curve, hash_algo, { r, s }, message, publicKey) {
16720 const jwk = rawPublicToJwk(curve.payloadSize, webCurves[curve.name], publicKey);
16721 const key = await webCrypto$7.importKey(
16722 "jwk",
16723 jwk,
16724 {
16725 "name": "ECDSA",
16726 "namedCurve": webCurves[curve.name],
16727 "hash": { name: enums.read(enums.webHash, curve.hash) }
16728 },
16729 false,
16730 ["verify"]
16731 );
16732
16733 const signature = util.concatUint8Array([r, s]).buffer;
16734
16735 return webCrypto$7.verify(
16736 {
16737 "name": 'ECDSA',
16738 "namedCurve": webCurves[curve.name],
16739 "hash": { name: enums.read(enums.webHash, hash_algo) }
16740 },
16741 key,
16742 signature,
16743 message
16744 );
16745}
16746
16747async function nodeSign$1(curve, hash_algo, message, keyPair) {
16748 const sign = nodeCrypto$8.createSign(enums.read(enums.hash, hash_algo));
16749 sign.write(message);
16750 sign.end();
16751 const key = ECPrivateKey.encode({
16752 version: 1,
16753 parameters: curve.oid,
16754 privateKey: Array.from(keyPair.privateKey),
16755 publicKey: { unused: 0, data: Array.from(keyPair.publicKey) }
16756 }, 'pem', {
16757 label: 'EC PRIVATE KEY'
16758 });
16759
16760 return ECDSASignature.decode(sign.sign(key), 'der');
16761}
16762
16763async function nodeVerify$1(curve, hash_algo, { r, s }, message, publicKey) {
16764 const { default: BN } = await import('./bn.mjs');
16765
16766 const verify = nodeCrypto$8.createVerify(enums.read(enums.hash, hash_algo));
16767 verify.write(message);
16768 verify.end();
16769 const key = SubjectPublicKeyInfo.encode({
16770 algorithm: {
16771 algorithm: [1, 2, 840, 10045, 2, 1],
16772 parameters: curve.oid
16773 },
16774 subjectPublicKey: { unused: 0, data: Array.from(publicKey) }
16775 }, 'pem', {
16776 label: 'PUBLIC KEY'
16777 });
16778 const signature = ECDSASignature.encode({
16779 r: new BN(r), s: new BN(s)
16780 }, 'der');
16781
16782 try {
16783 return verify.verify(key, signature);
16784 } catch (err) {
16785 return false;
16786 }
16787}
16788
16789// Originally written by Owen Smith https://github.com/omsmith
16790// Adapted on Feb 2018 from https://github.com/Brightspace/node-jwk-to-pem/
16791
16792/* eslint-disable no-invalid-this */
16793
16794const asn1$1 = nodeCrypto$8 ? void('asn1.js') : undefined;
16795
16796const ECDSASignature = nodeCrypto$8 ?
16797 asn1$1.define('ECDSASignature', function() {
16798 this.seq().obj(
16799 this.key('r').int(),
16800 this.key('s').int()
16801 );
16802 }) : undefined;
16803
16804const ECPrivateKey = nodeCrypto$8 ?
16805 asn1$1.define('ECPrivateKey', function() {
16806 this.seq().obj(
16807 this.key('version').int(),
16808 this.key('privateKey').octstr(),
16809 this.key('parameters').explicit(0).optional().any(),
16810 this.key('publicKey').explicit(1).optional().bitstr()
16811 );
16812 }) : undefined;
16813
16814const AlgorithmIdentifier = nodeCrypto$8 ?
16815 asn1$1.define('AlgorithmIdentifier', function() {
16816 this.seq().obj(
16817 this.key('algorithm').objid(),
16818 this.key('parameters').optional().any()
16819 );
16820 }) : undefined;
16821
16822const SubjectPublicKeyInfo = nodeCrypto$8 ?
16823 asn1$1.define('SubjectPublicKeyInfo', function() {
16824 this.seq().obj(
16825 this.key('algorithm').use(AlgorithmIdentifier),
16826 this.key('subjectPublicKey').bitstr()
16827 );
16828 }) : undefined;
16829
16830var ecdsa = /*#__PURE__*/Object.freeze({
16831 __proto__: null,
16832 sign: sign$1,
16833 verify: verify$1,
16834 validateParams: validateParams$2
16835});
16836
16837// OpenPGP.js - An OpenPGP implementation in javascript
16838
16839naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
16840
16841/**
16842 * Sign a message using the provided key
16843 * @param {module:type/oid} oid - Elliptic curve object identifier
16844 * @param {module:enums.hash} hash_algo - Hash algorithm used to sign
16845 * @param {Uint8Array} message - Message to sign
16846 * @param {Uint8Array} publicKey - Public key
16847 * @param {Uint8Array} privateKey - Private key used to sign the message
16848 * @param {Uint8Array} hashed - The hashed message
16849 * @returns {{r: Uint8Array,
16850 * s: Uint8Array}} Signature of the message
16851 * @async
16852 */
16853async function sign$2(oid, hash_algo, message, publicKey, privateKey, hashed) {
16854 const secretKey = util.concatUint8Array([privateKey, publicKey.subarray(1)]);
16855 const signature = naclFastLight.sign.detached(hashed, secretKey);
16856 // EdDSA signature params are returned in little-endian format
16857 return {
16858 r: signature.subarray(0, 32),
16859 s: signature.subarray(32)
16860 };
16861}
16862
16863/**
16864 * Verifies if a signature is valid for a message
16865 * @param {module:type/oid} oid - Elliptic curve object identifier
16866 * @param {module:enums.hash} hash_algo - Hash algorithm used in the signature
16867 * @param {{r: Uint8Array,
16868 s: Uint8Array}} signature Signature to verify the message
16869 * @param {Uint8Array} m - Message to verify
16870 * @param {Uint8Array} publicKey - Public key used to verify the message
16871 * @param {Uint8Array} hashed - The hashed message
16872 * @returns {Boolean}
16873 * @async
16874 */
16875async function verify$2(oid, hash_algo, { r, s }, m, publicKey, hashed) {
16876 const signature = util.concatUint8Array([r, s]);
16877 return naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1));
16878}
16879/**
16880 * Validate EdDSA parameters
16881 * @param {module:type/oid} oid - Elliptic curve object identifier
16882 * @param {Uint8Array} Q - EdDSA public point
16883 * @param {Uint8Array} k - EdDSA secret seed
16884 * @returns {Boolean} Whether params are valid.
16885 * @async
16886 */
16887async function validateParams$3(oid, Q, k) {
16888 // Check whether the given curve is supported
16889 if (oid.getName() !== 'ed25519') {
16890 return false;
16891 }
16892
16893 /**
16894 * Derive public point Q' = dG from private key
16895 * and expect Q == Q'
16896 */
16897 const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
16898 const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
16899 return util.equalsUint8Array(Q, dG);
16900}
16901
16902var eddsa = /*#__PURE__*/Object.freeze({
16903 __proto__: null,
16904 sign: sign$2,
16905 verify: verify$2,
16906 validateParams: validateParams$3
16907});
16908
16909// OpenPGP.js - An OpenPGP implementation in javascript
16910
16911/**
16912 * AES key wrap
16913 * @function
16914 * @param {Uint8Array} key
16915 * @param {Uint8Array} data
16916 * @returns {Uint8Array}
16917 */
16918function wrap(key, data) {
16919 const aes = new cipher["aes" + (key.length * 8)](key);
16920 const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
16921 const P = unpack(data);
16922 let A = IV;
16923 const R = P;
16924 const n = P.length / 2;
16925 const t = new Uint32Array([0, 0]);
16926 let B = new Uint32Array(4);
16927 for (let j = 0; j <= 5; ++j) {
16928 for (let i = 0; i < n; ++i) {
16929 t[1] = n * j + (1 + i);
16930 // B = A
16931 B[0] = A[0];
16932 B[1] = A[1];
16933 // B = A || R[i]
16934 B[2] = R[2 * i];
16935 B[3] = R[2 * i + 1];
16936 // B = AES(K, B)
16937 B = unpack(aes.encrypt(pack(B)));
16938 // A = MSB(64, B) ^ t
16939 A = B.subarray(0, 2);
16940 A[0] ^= t[0];
16941 A[1] ^= t[1];
16942 // R[i] = LSB(64, B)
16943 R[2 * i] = B[2];
16944 R[2 * i + 1] = B[3];
16945 }
16946 }
16947 return pack(A, R);
16948}
16949
16950/**
16951 * AES key unwrap
16952 * @function
16953 * @param {String} key
16954 * @param {String} data
16955 * @returns {Uint8Array}
16956 * @throws {Error}
16957 */
16958function unwrap(key, data) {
16959 const aes = new cipher["aes" + (key.length * 8)](key);
16960 const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
16961 const C = unpack(data);
16962 let A = C.subarray(0, 2);
16963 const R = C.subarray(2);
16964 const n = C.length / 2 - 1;
16965 const t = new Uint32Array([0, 0]);
16966 let B = new Uint32Array(4);
16967 for (let j = 5; j >= 0; --j) {
16968 for (let i = n - 1; i >= 0; --i) {
16969 t[1] = n * j + (i + 1);
16970 // B = A ^ t
16971 B[0] = A[0] ^ t[0];
16972 B[1] = A[1] ^ t[1];
16973 // B = (A ^ t) || R[i]
16974 B[2] = R[2 * i];
16975 B[3] = R[2 * i + 1];
16976 // B = AES-1(B)
16977 B = unpack(aes.decrypt(pack(B)));
16978 // A = MSB(64, B)
16979 A = B.subarray(0, 2);
16980 // R[i] = LSB(64, B)
16981 R[2 * i] = B[2];
16982 R[2 * i + 1] = B[3];
16983 }
16984 }
16985 if (A[0] === IV[0] && A[1] === IV[1]) {
16986 return pack(R);
16987 }
16988 throw new Error("Key Data Integrity failed");
16989}
16990
16991function createArrayBuffer(data) {
16992 if (util.isString(data)) {
16993 const { length } = data;
16994 const buffer = new ArrayBuffer(length);
16995 const view = new Uint8Array(buffer);
16996 for (let j = 0; j < length; ++j) {
16997 view[j] = data.charCodeAt(j);
16998 }
16999 return buffer;
17000 }
17001 return new Uint8Array(data).buffer;
17002}
17003
17004function unpack(data) {
17005 const { length } = data;
17006 const buffer = createArrayBuffer(data);
17007 const view = new DataView(buffer);
17008 const arr = new Uint32Array(length / 4);
17009 for (let i = 0; i < length / 4; ++i) {
17010 arr[i] = view.getUint32(4 * i);
17011 }
17012 return arr;
17013}
17014
17015function pack() {
17016 let length = 0;
17017 for (let k = 0; k < arguments.length; ++k) {
17018 length += 4 * arguments[k].length;
17019 }
17020 const buffer = new ArrayBuffer(length);
17021 const view = new DataView(buffer);
17022 let offset = 0;
17023 for (let i = 0; i < arguments.length; ++i) {
17024 for (let j = 0; j < arguments[i].length; ++j) {
17025 view.setUint32(offset + 4 * j, arguments[i][j]);
17026 }
17027 offset += 4 * arguments[i].length;
17028 }
17029 return new Uint8Array(buffer);
17030}
17031
17032var aes_kw = /*#__PURE__*/Object.freeze({
17033 __proto__: null,
17034 wrap: wrap,
17035 unwrap: unwrap
17036});
17037
17038// OpenPGP.js - An OpenPGP implementation in javascript
17039
17040/**
17041 * @fileoverview Functions to add and remove PKCS5 padding
17042 * @see PublicKeyEncryptedSessionKeyPacket
17043 * @module crypto/pkcs5
17044 * @private
17045 */
17046
17047/**
17048 * Add pkcs5 padding to a message
17049 * @param {Uint8Array} message - message to pad
17050 * @returns {Uint8Array} Padded message.
17051 */
17052function encode$1(message) {
17053 const c = 8 - (message.length % 8);
17054 const padded = new Uint8Array(message.length + c).fill(c);
17055 padded.set(message);
17056 return padded;
17057}
17058
17059/**
17060 * Remove pkcs5 padding from a message
17061 * @param {Uint8Array} message - message to remove padding from
17062 * @returns {Uint8Array} Message without padding.
17063 */
17064function decode$1(message) {
17065 const len = message.length;
17066 if (len > 0) {
17067 const c = message[len - 1];
17068 if (c >= 1) {
17069 const provided = message.subarray(len - c);
17070 const computed = new Uint8Array(c).fill(c);
17071 if (util.equalsUint8Array(provided, computed)) {
17072 return message.subarray(0, len - c);
17073 }
17074 }
17075 }
17076 throw new Error('Invalid padding');
17077}
17078
17079var pkcs5 = /*#__PURE__*/Object.freeze({
17080 __proto__: null,
17081 encode: encode$1,
17082 decode: decode$1
17083});
17084
17085// OpenPGP.js - An OpenPGP implementation in javascript
17086
17087const webCrypto$8 = util.getWebCrypto();
17088const nodeCrypto$9 = util.getNodeCrypto();
17089
17090/**
17091 * Validate ECDH parameters
17092 * @param {module:type/oid} oid - Elliptic curve object identifier
17093 * @param {Uint8Array} Q - ECDH public point
17094 * @param {Uint8Array} d - ECDH secret scalar
17095 * @returns {Boolean} Whether params are valid.
17096 * @async
17097 */
17098async function validateParams$4(oid, Q, d) {
17099 return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
17100}
17101
17102// Build Param for ECDH algorithm (RFC 6637)
17103function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) {
17104 return util.concatUint8Array([
17105 oid.write(),
17106 new Uint8Array([public_algo]),
17107 kdfParams.write(),
17108 util.strToUint8Array("Anonymous Sender "),
17109 fingerprint.subarray(0, 20)
17110 ]);
17111}
17112
17113// Key Derivation Function (RFC 6637)
17114async function kdf(hash_algo, X, length, param, stripLeading = false, stripTrailing = false) {
17115 // Note: X is little endian for Curve25519, big-endian for all others.
17116 // This is not ideal, but the RFC's are unclear
17117 // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
17118 let i;
17119 if (stripLeading) {
17120 // Work around old go crypto bug
17121 for (i = 0; i < X.length && X[i] === 0; i++);
17122 X = X.subarray(i);
17123 }
17124 if (stripTrailing) {
17125 // Work around old OpenPGP.js bug
17126 for (i = X.length - 1; i >= 0 && X[i] === 0; i--);
17127 X = X.subarray(0, i + 1);
17128 }
17129 const digest = await hash.digest(hash_algo, util.concatUint8Array([
17130 new Uint8Array([0, 0, 0, 1]),
17131 X,
17132 param
17133 ]));
17134 return digest.subarray(0, length);
17135}
17136
17137/**
17138 * Generate ECDHE ephemeral key and secret from public key
17139 *
17140 * @param {Curve} curve - Elliptic curve object
17141 * @param {Uint8Array} Q - Recipient public key
17142 * @returns {{publicKey: Uint8Array, sharedKey: Uint8Array}}
17143 * @async
17144 */
17145async function genPublicEphemeralKey(curve, Q) {
17146 switch (curve.type) {
17147 case 'curve25519': {
17148 const d = await getRandomBytes(32);
17149 const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d);
17150 let { publicKey } = naclFastLight.box.keyPair.fromSecretKey(secretKey);
17151 publicKey = util.concatUint8Array([new Uint8Array([0x40]), publicKey]);
17152 return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
17153 }
17154 case 'web':
17155 if (curve.web && util.getWebCrypto()) {
17156 try {
17157 return await webPublicEphemeralKey(curve, Q);
17158 } catch (err) {
17159 util.printDebugError(err);
17160 }
17161 }
17162 break;
17163 case 'node':
17164 return nodePublicEphemeralKey(curve, Q);
17165 }
17166 return ellipticPublicEphemeralKey(curve, Q);
17167}
17168
17169/**
17170 * Encrypt and wrap a session key
17171 *
17172 * @param {module:type/oid} oid - Elliptic curve object identifier
17173 * @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use
17174 * @param {Uint8Array} data - Unpadded session key data
17175 * @param {Uint8Array} Q - Recipient public key
17176 * @param {Uint8Array} fingerprint - Recipient fingerprint
17177 * @returns {{publicKey: Uint8Array, wrappedKey: Uint8Array}}
17178 * @async
17179 */
17180async function encrypt$3(oid, kdfParams, data, Q, fingerprint) {
17181 const m = encode$1(data);
17182
17183 const curve = new Curve(oid);
17184 const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
17185 const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
17186 const cipher_algo = enums.read(enums.symmetric, kdfParams.cipher);
17187 const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipher_algo].keySize, param);
17188 const wrappedKey = wrap(Z, m);
17189 return { publicKey, wrappedKey };
17190}
17191
17192/**
17193 * Generate ECDHE secret from private key and public part of ephemeral key
17194 *
17195 * @param {Curve} curve - Elliptic curve object
17196 * @param {Uint8Array} V - Public part of ephemeral key
17197 * @param {Uint8Array} Q - Recipient public key
17198 * @param {Uint8Array} d - Recipient private key
17199 * @returns {{secretKey: Uint8Array, sharedKey: Uint8Array}}
17200 * @async
17201 */
17202async function genPrivateEphemeralKey(curve, V, Q, d) {
17203 if (d.length !== curve.payloadSize) {
17204 const privateKey = new Uint8Array(curve.payloadSize);
17205 privateKey.set(d, curve.payloadSize - d.length);
17206 d = privateKey;
17207 }
17208 switch (curve.type) {
17209 case 'curve25519': {
17210 const secretKey = d.slice().reverse();
17211 const sharedKey = naclFastLight.scalarMult(secretKey, V.subarray(1));
17212 return { secretKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
17213 }
17214 case 'web':
17215 if (curve.web && util.getWebCrypto()) {
17216 try {
17217 return await webPrivateEphemeralKey(curve, V, Q, d);
17218 } catch (err) {
17219 util.printDebugError(err);
17220 }
17221 }
17222 break;
17223 case 'node':
17224 return nodePrivateEphemeralKey(curve, V, d);
17225 }
17226 return ellipticPrivateEphemeralKey(curve, V, d);
17227}
17228
17229/**
17230 * Decrypt and unwrap the value derived from session key
17231 *
17232 * @param {module:type/oid} oid - Elliptic curve object identifier
17233 * @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use
17234 * @param {Uint8Array} V - Public part of ephemeral key
17235 * @param {Uint8Array} C - Encrypted and wrapped value derived from session key
17236 * @param {Uint8Array} Q - Recipient public key
17237 * @param {Uint8Array} d - Recipient private key
17238 * @param {Uint8Array} fingerprint - Recipient fingerprint
17239 * @returns {Uint8Array} Value derived from session key.
17240 * @async
17241 */
17242async function decrypt$3(oid, kdfParams, V, C, Q, d, fingerprint) {
17243 const curve = new Curve(oid);
17244 const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
17245 const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
17246 const cipher_algo = enums.read(enums.symmetric, kdfParams.cipher);
17247 let err;
17248 for (let i = 0; i < 3; i++) {
17249 try {
17250 // Work around old go crypto bug and old OpenPGP.js bug, respectively.
17251 const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipher_algo].keySize, param, i === 1, i === 2);
17252 return decode$1(unwrap(Z, C));
17253 } catch (e) {
17254 err = e;
17255 }
17256 }
17257 throw err;
17258}
17259
17260/**
17261 * Generate ECDHE secret from private key and public part of ephemeral key using webCrypto
17262 *
17263 * @param {Curve} curve - Elliptic curve object
17264 * @param {Uint8Array} V - Public part of ephemeral key
17265 * @param {Uint8Array} Q - Recipient public key
17266 * @param {Uint8Array} d - Recipient private key
17267 * @returns {{secretKey: Uint8Array, sharedKey: Uint8Array}}
17268 * @async
17269 */
17270async function webPrivateEphemeralKey(curve, V, Q, d) {
17271 const recipient = privateToJwk$1(curve.payloadSize, curve.web.web, Q, d);
17272 let privateKey = webCrypto$8.importKey(
17273 "jwk",
17274 recipient,
17275 {
17276 name: "ECDH",
17277 namedCurve: curve.web.web
17278 },
17279 true,
17280 ["deriveKey", "deriveBits"]
17281 );
17282 const jwk = rawPublicToJwk(curve.payloadSize, curve.web.web, V);
17283 let sender = webCrypto$8.importKey(
17284 "jwk",
17285 jwk,
17286 {
17287 name: "ECDH",
17288 namedCurve: curve.web.web
17289 },
17290 true,
17291 []
17292 );
17293 [privateKey, sender] = await Promise.all([privateKey, sender]);
17294 let S = webCrypto$8.deriveBits(
17295 {
17296 name: "ECDH",
17297 namedCurve: curve.web.web,
17298 public: sender
17299 },
17300 privateKey,
17301 curve.web.sharedSize
17302 );
17303 let secret = webCrypto$8.exportKey(
17304 "jwk",
17305 privateKey
17306 );
17307 [S, secret] = await Promise.all([S, secret]);
17308 const sharedKey = new Uint8Array(S);
17309 const secretKey = b64ToUint8Array(secret.d);
17310 return { secretKey, sharedKey };
17311}
17312
17313/**
17314 * Generate ECDHE ephemeral key and secret from public key using webCrypto
17315 *
17316 * @param {Curve} curve - Elliptic curve object
17317 * @param {Uint8Array} Q - Recipient public key
17318 * @returns {{publicKey: Uint8Array, sharedKey: Uint8Array}}
17319 * @async
17320 */
17321async function webPublicEphemeralKey(curve, Q) {
17322 const jwk = rawPublicToJwk(curve.payloadSize, curve.web.web, Q);
17323 let keyPair = webCrypto$8.generateKey(
17324 {
17325 name: "ECDH",
17326 namedCurve: curve.web.web
17327 },
17328 true,
17329 ["deriveKey", "deriveBits"]
17330 );
17331 let recipient = webCrypto$8.importKey(
17332 "jwk",
17333 jwk,
17334 {
17335 name: "ECDH",
17336 namedCurve: curve.web.web
17337 },
17338 false,
17339 []
17340 );
17341 [keyPair, recipient] = await Promise.all([keyPair, recipient]);
17342 let s = webCrypto$8.deriveBits(
17343 {
17344 name: "ECDH",
17345 namedCurve: curve.web.web,
17346 public: recipient
17347 },
17348 keyPair.privateKey,
17349 curve.web.sharedSize
17350 );
17351 let p = webCrypto$8.exportKey(
17352 "jwk",
17353 keyPair.publicKey
17354 );
17355 [s, p] = await Promise.all([s, p]);
17356 const sharedKey = new Uint8Array(s);
17357 const publicKey = new Uint8Array(jwkToRawPublic(p));
17358 return { publicKey, sharedKey };
17359}
17360
17361/**
17362 * Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic
17363 *
17364 * @param {Curve} curve - Elliptic curve object
17365 * @param {Uint8Array} V - Public part of ephemeral key
17366 * @param {Uint8Array} d - Recipient private key
17367 * @returns {{secretKey: Uint8Array, sharedKey: Uint8Array}}
17368 * @async
17369 */
17370async function ellipticPrivateEphemeralKey(curve, V, d) {
17371 const indutnyCurve = await getIndutnyCurve(curve.name);
17372 V = keyFromPublic(indutnyCurve, V);
17373 d = keyFromPrivate(indutnyCurve, d);
17374 const secretKey = new Uint8Array(d.getPrivate());
17375 const S = d.derive(V.getPublic());
17376 const len = indutnyCurve.curve.p.byteLength();
17377 const sharedKey = S.toArrayLike(Uint8Array, 'be', len);
17378 return { secretKey, sharedKey };
17379}
17380
17381/**
17382 * Generate ECDHE ephemeral key and secret from public key using indutny/elliptic
17383 *
17384 * @param {Curve} curve - Elliptic curve object
17385 * @param {Uint8Array} Q - Recipient public key
17386 * @returns {{publicKey: Uint8Array, sharedKey: Uint8Array}}
17387 * @async
17388 */
17389async function ellipticPublicEphemeralKey(curve, Q) {
17390 const indutnyCurve = await getIndutnyCurve(curve.name);
17391 const v = await curve.genKeyPair();
17392 Q = keyFromPublic(indutnyCurve, Q);
17393 const V = keyFromPrivate(indutnyCurve, v.privateKey);
17394 const publicKey = v.publicKey;
17395 const S = V.derive(Q.getPublic());
17396 const len = indutnyCurve.curve.p.byteLength();
17397 const sharedKey = S.toArrayLike(Uint8Array, 'be', len);
17398 return { publicKey, sharedKey };
17399}
17400
17401/**
17402 * Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto
17403 *
17404 * @param {Curve} curve - Elliptic curve object
17405 * @param {Uint8Array} V - Public part of ephemeral key
17406 * @param {Uint8Array} d - Recipient private key
17407 * @returns {{secretKey: Uint8Array, sharedKey: Uint8Array}}
17408 * @async
17409 */
17410async function nodePrivateEphemeralKey(curve, V, d) {
17411 const recipient = nodeCrypto$9.createECDH(curve.node.node);
17412 recipient.setPrivateKey(d);
17413 const sharedKey = new Uint8Array(recipient.computeSecret(V));
17414 const secretKey = new Uint8Array(recipient.getPrivateKey());
17415 return { secretKey, sharedKey };
17416}
17417
17418/**
17419 * Generate ECDHE ephemeral key and secret from public key using nodeCrypto
17420 *
17421 * @param {Curve} curve - Elliptic curve object
17422 * @param {Uint8Array} Q - Recipient public key
17423 * @returns {{publicKey: Uint8Array, sharedKey: Uint8Array}}
17424 * @async
17425 */
17426async function nodePublicEphemeralKey(curve, Q) {
17427 const sender = nodeCrypto$9.createECDH(curve.node.node);
17428 sender.generateKeys();
17429 const sharedKey = new Uint8Array(sender.computeSecret(Q));
17430 const publicKey = new Uint8Array(sender.getPublicKey());
17431 return { publicKey, sharedKey };
17432}
17433
17434var ecdh = /*#__PURE__*/Object.freeze({
17435 __proto__: null,
17436 validateParams: validateParams$4,
17437 encrypt: encrypt$3,
17438 decrypt: decrypt$3
17439});
17440
17441// OpenPGP.js - An OpenPGP implementation in javascript
17442
17443var elliptic = /*#__PURE__*/Object.freeze({
17444 __proto__: null,
17445 Curve: Curve,
17446 ecdh: ecdh,
17447 ecdsa: ecdsa,
17448 eddsa: eddsa,
17449 generate: generate$1,
17450 getPreferredHashAlgo: getPreferredHashAlgo
17451});
17452
17453// GPG4Browsers - An OpenPGP implementation in javascript
17454
17455/*
17456 TODO regarding the hash function, read:
17457 https://tools.ietf.org/html/rfc4880#section-13.6
17458 https://tools.ietf.org/html/rfc4880#section-14
17459*/
17460
17461/**
17462 * DSA Sign function
17463 * @param {Integer} hash_algo
17464 * @param {Uint8Array} hashed
17465 * @param {Uint8Array} g
17466 * @param {Uint8Array} p
17467 * @param {Uint8Array} q
17468 * @param {Uint8Array} x
17469 * @returns {{ r: Uint8Array, s: Uint8Array }}
17470 * @async
17471 */
17472async function sign$3(hash_algo, hashed, g, p, q, x) {
17473 const BigInteger = await util.getBigInteger();
17474 const one = new BigInteger(1);
17475 p = new BigInteger(p);
17476 q = new BigInteger(q);
17477 g = new BigInteger(g);
17478 x = new BigInteger(x);
17479
17480 let k;
17481 let r;
17482 let s;
17483 let t;
17484 g = g.mod(p);
17485 x = x.mod(q);
17486 // If the output size of the chosen hash is larger than the number of
17487 // bits of q, the hash result is truncated to fit by taking the number
17488 // of leftmost bits equal to the number of bits of q. This (possibly
17489 // truncated) hash function result is treated as a number and used
17490 // directly in the DSA signature algorithm.
17491 const h = new BigInteger(hashed.subarray(0, q.byteLength())).mod(q);
17492 // FIPS-186-4, section 4.6:
17493 // The values of r and s shall be checked to determine if r = 0 or s = 0.
17494 // If either r = 0 or s = 0, a new value of k shall be generated, and the
17495 // signature shall be recalculated. It is extremely unlikely that r = 0
17496 // or s = 0 if signatures are generated properly.
17497 while (true) {
17498 // See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
17499 k = await getRandomBigInteger(one, q); // returns in [1, q-1]
17500 r = g.modExp(k, p).imod(q); // (g**k mod p) mod q
17501 if (r.isZero()) {
17502 continue;
17503 }
17504 const xr = x.mul(r).imod(q);
17505 t = h.add(xr).imod(q); // H(m) + x*r mod q
17506 s = k.modInv(q).imul(t).imod(q); // k**-1 * (H(m) + x*r) mod q
17507 if (s.isZero()) {
17508 continue;
17509 }
17510 break;
17511 }
17512 return {
17513 r: r.toUint8Array('be', q.byteLength()),
17514 s: s.toUint8Array('be', q.byteLength())
17515 };
17516}
17517
17518/**
17519 * DSA Verify function
17520 * @param {Integer} hash_algo
17521 * @param {Uint8Array} r
17522 * @param {Uint8Array} s
17523 * @param {Uint8Array} hashed
17524 * @param {Uint8Array} g
17525 * @param {Uint8Array} p
17526 * @param {Uint8Array} q
17527 * @param {Uint8Array} y
17528 * @returns {boolean}
17529 * @async
17530 */
17531async function verify$3(hash_algo, r, s, hashed, g, p, q, y) {
17532 const BigInteger = await util.getBigInteger();
17533 const zero = new BigInteger(0);
17534 r = new BigInteger(r);
17535 s = new BigInteger(s);
17536
17537 p = new BigInteger(p);
17538 q = new BigInteger(q);
17539 g = new BigInteger(g);
17540 y = new BigInteger(y);
17541
17542 if (r.lte(zero) || r.gte(q) ||
17543 s.lte(zero) || s.gte(q)) {
17544 util.printDebug("invalid DSA Signature");
17545 return false;
17546 }
17547 const h = new BigInteger(hashed.subarray(0, q.byteLength())).imod(q);
17548 const w = s.modInv(q); // s**-1 mod q
17549 if (w.isZero()) {
17550 util.printDebug("invalid DSA Signature");
17551 return false;
17552 }
17553
17554 g = g.mod(p);
17555 y = y.mod(p);
17556 const u1 = h.mul(w).imod(q); // H(m) * w mod q
17557 const u2 = r.mul(w).imod(q); // r * w mod q
17558 const t1 = g.modExp(u1, p); // g**u1 mod p
17559 const t2 = y.modExp(u2, p); // y**u2 mod p
17560 const v = t1.mul(t2).imod(p).imod(q); // (g**u1 * y**u2 mod p) mod q
17561 return v.equal(r);
17562}
17563
17564/**
17565 * Validate DSA parameters
17566 * @param {Uint8Array} p - DSA prime
17567 * @param {Uint8Array} q - DSA group order
17568 * @param {Uint8Array} g - DSA sub-group generator
17569 * @param {Uint8Array} y - DSA public key
17570 * @param {Uint8Array} x - DSA private key
17571 * @returns {Boolean} Whether params are valid.
17572 * @async
17573 */
17574async function validateParams$5(p, q, g, y, x) {
17575 const BigInteger = await util.getBigInteger();
17576 p = new BigInteger(p);
17577 q = new BigInteger(q);
17578 g = new BigInteger(g);
17579 y = new BigInteger(y);
17580 const one = new BigInteger(1);
17581 // Check that 1 < g < p
17582 if (g.lte(one) || g.gte(p)) {
17583 return false;
17584 }
17585
17586 /**
17587 * Check that subgroup order q divides p-1
17588 */
17589 if (!p.dec().mod(q).isZero()) {
17590 return false;
17591 }
17592
17593 /**
17594 * g has order q
17595 * Check that g ** q = 1 mod p
17596 */
17597 if (!g.modExp(q, p).isOne()) {
17598 return false;
17599 }
17600
17601 /**
17602 * Check q is large and probably prime (we mainly want to avoid small factors)
17603 */
17604 const qSize = new BigInteger(q.bitLength());
17605 const n150 = new BigInteger(150);
17606 if (qSize.lt(n150) || !(await isProbablePrime(q, null, 32))) {
17607 return false;
17608 }
17609
17610 /**
17611 * Re-derive public key y' = g ** x mod p
17612 * Expect y == y'
17613 *
17614 * Blinded exponentiation computes g**{rq + x} to compare to y
17615 */
17616 x = new BigInteger(x);
17617 const two = new BigInteger(2);
17618 const r = await getRandomBigInteger(two.leftShift(qSize.dec()), two.leftShift(qSize)); // draw r of same size as q
17619 const rqx = q.mul(r).add(x);
17620 if (!y.equal(g.modExp(rqx, p))) {
17621 return false;
17622 }
17623
17624 return true;
17625}
17626
17627var dsa = /*#__PURE__*/Object.freeze({
17628 __proto__: null,
17629 sign: sign$3,
17630 verify: verify$3,
17631 validateParams: validateParams$5
17632});
17633
17634/**
17635 * @fileoverview Asymmetric cryptography functions
17636 * @module crypto/public_key
17637 * @private
17638 */
17639
17640var publicKey = {
17641 /** @see module:crypto/public_key/rsa */
17642 rsa: rsa,
17643 /** @see module:crypto/public_key/elgamal */
17644 elgamal: elgamal,
17645 /** @see module:crypto/public_key/elliptic */
17646 elliptic: elliptic,
17647 /** @see module:crypto/public_key/dsa */
17648 dsa: dsa,
17649 /** @see tweetnacl */
17650 nacl: naclFastLight
17651};
17652
17653/**
17654 * @fileoverview Provides functions for asymmetric signing and signature verification
17655 * @module crypto/signature
17656 * @private
17657 */
17658
17659/**
17660 * Parse signature in binary form to get the parameters.
17661 * The returned values are only padded for EdDSA, since in the other cases their expected length
17662 * depends on the key params, hence we delegate the padding to the signature verification function.
17663 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}
17664 * See {@link https://tools.ietf.org/html/rfc4880#section-5.2.2|RFC 4880 5.2.2.}
17665 * @param {module:enums.publicKey} algo - Public key algorithm
17666 * @param {Uint8Array} signature - Data for which the signature was created
17667 * @returns {Object} True if signature is valid.
17668 * @async
17669 */
17670function parseSignatureParams(algo, signature) {
17671 let read = 0;
17672 switch (algo) {
17673 // Algorithm-Specific Fields for RSA signatures:
17674 // - MPI of RSA signature value m**d mod n.
17675 case enums.publicKey.rsaEncryptSign:
17676 case enums.publicKey.rsaEncrypt:
17677 case enums.publicKey.rsaSign: {
17678 const s = util.readMPI(signature.subarray(read));
17679 // The signature needs to be the same length as the public key modulo n.
17680 // We pad s on signature verification, where we have access to n.
17681 return { s };
17682 }
17683 // Algorithm-Specific Fields for DSA or ECDSA signatures:
17684 // - MPI of DSA or ECDSA value r.
17685 // - MPI of DSA or ECDSA value s.
17686 case enums.publicKey.dsa:
17687 case enums.publicKey.ecdsa:
17688 {
17689 const r = util.readMPI(signature.subarray(read)); read += r.length + 2;
17690 const s = util.readMPI(signature.subarray(read));
17691 return { r, s };
17692 }
17693 // Algorithm-Specific Fields for EdDSA signatures:
17694 // - MPI of an EC point r.
17695 // - EdDSA value s, in MPI, in the little endian representation
17696 case enums.publicKey.eddsa: {
17697 // When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
17698 // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
17699 let r = util.readMPI(signature.subarray(read)); read += r.length + 2;
17700 r = util.leftPad(r, 32);
17701 let s = util.readMPI(signature.subarray(read));
17702 s = util.leftPad(s, 32);
17703 return { r, s };
17704 }
17705 default:
17706 throw new Error('Invalid signature algorithm.');
17707 }
17708}
17709
17710/**
17711 * Verifies the signature provided for data using specified algorithms and public key parameters.
17712 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}
17713 * and {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4}
17714 * for public key and hash algorithms.
17715 * @param {module:enums.publicKey} algo - Public key algorithm
17716 * @param {module:enums.hash} hashAlgo - Hash algorithm
17717 * @param {Object} signature - Named algorithm-specific signature parameters
17718 * @param {Object} publicParams - Algorithm-specific public key parameters
17719 * @param {Uint8Array} data - Data for which the signature was created
17720 * @param {Uint8Array} hashed - The hashed data
17721 * @returns {Boolean} True if signature is valid.
17722 * @async
17723 */
17724async function verify$4(algo, hashAlgo, signature, publicParams, data, hashed) {
17725 switch (algo) {
17726 case enums.publicKey.rsaEncryptSign:
17727 case enums.publicKey.rsaEncrypt:
17728 case enums.publicKey.rsaSign: {
17729 const { n, e } = publicParams;
17730 const s = util.leftPad(signature.s, n.length); // padding needed for webcrypto and node crypto
17731 return publicKey.rsa.verify(hashAlgo, data, s, n, e, hashed);
17732 }
17733 case enums.publicKey.dsa: {
17734 const { g, p, q, y } = publicParams;
17735 const { r, s } = signature; // no need to pad, since we always handle them as BigIntegers
17736 return publicKey.dsa.verify(hashAlgo, r, s, hashed, g, p, q, y);
17737 }
17738 case enums.publicKey.ecdsa: {
17739 const { oid, Q } = publicParams;
17740 const curveSize = new publicKey.elliptic.Curve(oid).payloadSize;
17741 // padding needed for webcrypto
17742 const r = util.leftPad(signature.r, curveSize);
17743 const s = util.leftPad(signature.s, curveSize);
17744 return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
17745 }
17746 case enums.publicKey.eddsa: {
17747 const { oid, Q } = publicParams;
17748 // signature already padded on parsing
17749 return publicKey.elliptic.eddsa.verify(oid, hashAlgo, signature, data, Q, hashed);
17750 }
17751 default:
17752 throw new Error('Invalid signature algorithm.');
17753 }
17754}
17755
17756/**
17757 * Creates a signature on data using specified algorithms and private key parameters.
17758 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}
17759 * and {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4}
17760 * for public key and hash algorithms.
17761 * @param {module:enums.publicKey} algo - Public key algorithm
17762 * @param {module:enums.hash} hashAlgo - Hash algorithm
17763 * @param {Object} publicKeyParams - Algorithm-specific public and private key parameters
17764 * @param {Object} privateKeyParams - Algorithm-specific public and private key parameters
17765 * @param {Uint8Array} data - Data to be signed
17766 * @param {Uint8Array} hashed - The hashed data
17767 * @returns {Object} Signature Object containing named signature parameters.
17768 * @async
17769 */
17770async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
17771 if (!publicKeyParams || !privateKeyParams) {
17772 throw new Error('Missing key parameters');
17773 }
17774 switch (algo) {
17775 case enums.publicKey.rsaEncryptSign:
17776 case enums.publicKey.rsaEncrypt:
17777 case enums.publicKey.rsaSign: {
17778 const { n, e } = publicKeyParams;
17779 const { d, p, q, u } = privateKeyParams;
17780 const s = await publicKey.rsa.sign(hashAlgo, data, n, e, d, p, q, u, hashed);
17781 return { s };
17782 }
17783 case enums.publicKey.dsa: {
17784 const { g, p, q } = publicKeyParams;
17785 const { x } = privateKeyParams;
17786 return publicKey.dsa.sign(hashAlgo, hashed, g, p, q, x);
17787 }
17788 case enums.publicKey.elgamal: {
17789 throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
17790 }
17791 case enums.publicKey.ecdsa: {
17792 const { oid, Q } = publicKeyParams;
17793 const { d } = privateKeyParams;
17794 return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
17795 }
17796 case enums.publicKey.eddsa: {
17797 const { oid, Q } = publicKeyParams;
17798 const { seed } = privateKeyParams;
17799 return publicKey.elliptic.eddsa.sign(oid, hashAlgo, data, Q, seed, hashed);
17800 }
17801 default:
17802 throw new Error('Invalid signature algorithm.');
17803 }
17804}
17805
17806var signature = /*#__PURE__*/Object.freeze({
17807 __proto__: null,
17808 parseSignatureParams: parseSignatureParams,
17809 verify: verify$4,
17810 sign: sign$4
17811});
17812
17813// OpenPGP.js - An OpenPGP implementation in javascript
17814
17815class ECDHSymmetricKey {
17816 constructor(data) {
17817 if (typeof data === 'undefined') {
17818 data = new Uint8Array([]);
17819 } else if (util.isString(data)) {
17820 data = util.strToUint8Array(data);
17821 } else {
17822 data = new Uint8Array(data);
17823 }
17824 this.data = data;
17825 }
17826
17827 /**
17828 * Read an ECDHSymmetricKey from an Uint8Array
17829 * @param {Uint8Array} input - Where to read the encoded symmetric key from
17830 * @returns {Number} Number of read bytes.
17831 */
17832 read(input) {
17833 if (input.length >= 1) {
17834 const length = input[0];
17835 if (input.length >= 1 + length) {
17836 this.data = input.subarray(1, 1 + length);
17837 return 1 + this.data.length;
17838 }
17839 }
17840 throw new Error('Invalid symmetric key');
17841 }
17842
17843 /**
17844 * Write an ECDHSymmetricKey as an Uint8Array
17845 * @returns {Uint8Array} An array containing the value
17846 */
17847 write() {
17848 return util.concatUint8Array([new Uint8Array([this.data.length]), this.data]);
17849 }
17850}
17851
17852// OpenPGP.js - An OpenPGP implementation in javascript
17853// Copyright (C) 2015-2016 Decentral
17854//
17855// This library is free software; you can redistribute it and/or
17856// modify it under the terms of the GNU Lesser General Public
17857// License as published by the Free Software Foundation; either
17858// version 3.0 of the License, or (at your option) any later version.
17859//
17860// This library is distributed in the hope that it will be useful,
17861// but WITHOUT ANY WARRANTY; without even the implied warranty of
17862// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17863// Lesser General Public License for more details.
17864//
17865// You should have received a copy of the GNU Lesser General Public
17866// License along with this library; if not, write to the Free Software
17867// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17868
17869/**
17870 * Implementation of type KDF parameters
17871 *
17872 * {@link https://tools.ietf.org/html/rfc6637#section-7|RFC 6637 7}:
17873 * A key derivation function (KDF) is necessary to implement the EC
17874 * encryption. The Concatenation Key Derivation Function (Approved
17875 * Alternative 1) [NIST-SP800-56A] with the KDF hash function that is
17876 * SHA2-256 [FIPS-180-3] or stronger is REQUIRED.
17877 * @module type/kdf_params
17878 * @private
17879 */
17880
17881class KDFParams {
17882 /**
17883 * @param {enums.hash} hash - Hash algorithm
17884 * @param {enums.symmetric} cipher - Symmetric algorithm
17885 */
17886 constructor(data) {
17887 if (data) {
17888 const { hash, cipher } = data;
17889 this.hash = hash;
17890 this.cipher = cipher;
17891 } else {
17892 this.hash = null;
17893 this.cipher = null;
17894 }
17895 }
17896
17897 /**
17898 * Read KDFParams from an Uint8Array
17899 * @param {Uint8Array} input - Where to read the KDFParams from
17900 * @returns {Number} Number of read bytes.
17901 */
17902 read(input) {
17903 if (input.length < 4 || input[0] !== 3 || input[1] !== 1) {
17904 throw new Error('Cannot read KDFParams');
17905 }
17906 this.hash = input[2];
17907 this.cipher = input[3];
17908 return 4;
17909 }
17910
17911 /**
17912 * Write KDFParams to an Uint8Array
17913 * @returns {Uint8Array} Array with the KDFParams value
17914 */
17915 write() {
17916 return new Uint8Array([3, 1, this.hash, this.cipher]);
17917 }
17918}
17919
17920// GPG4Browsers - An OpenPGP implementation in javascript
17921
17922/**
17923 * Encrypts data using specified algorithm and public key parameters.
17924 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
17925 * @param {module:enums.publicKey} algo - Public key algorithm
17926 * @param {Object} publicParams - Algorithm-specific public key parameters
17927 * @param {Uint8Array} data - Data to be encrypted
17928 * @param {Uint8Array} fingerprint - Recipient fingerprint
17929 * @returns {Object} Encrypted session key parameters.
17930 * @async
17931 */
17932async function publicKeyEncrypt(algo, publicParams, data, fingerprint) {
17933 switch (algo) {
17934 case enums.publicKey.rsaEncrypt:
17935 case enums.publicKey.rsaEncryptSign: {
17936 const { n, e } = publicParams;
17937 const c = await publicKey.rsa.encrypt(data, n, e);
17938 return { c };
17939 }
17940 case enums.publicKey.elgamal: {
17941 const { p, g, y } = publicParams;
17942 return publicKey.elgamal.encrypt(data, p, g, y);
17943 }
17944 case enums.publicKey.ecdh: {
17945 const { oid, Q, kdfParams } = publicParams;
17946 const { publicKey: V, wrappedKey: C } = await publicKey.elliptic.ecdh.encrypt(
17947 oid, kdfParams, data, Q, fingerprint);
17948 return { V, C: new ECDHSymmetricKey(C) };
17949 }
17950 default:
17951 return [];
17952 }
17953}
17954
17955/**
17956 * Decrypts data using specified algorithm and private key parameters.
17957 * See {@link https://tools.ietf.org/html/rfc4880#section-5.5.3|RFC 4880 5.5.3}
17958 * @param {module:enums.publicKey} algo - Public key algorithm
17959 * @param {Object} publicKeyParams - Algorithm-specific public key parameters
17960 * @param {Object} privateKeyParams - Algorithm-specific private key parameters
17961 * @param {Object} sessionKeyParams - Encrypted session key parameters
17962 * @param {Uint8Array} fingerprint - Recipient fingerprint
17963 * @returns {Uint8Array} Decrypted data.
17964 * @async
17965 */
17966async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, sessionKeyParams, fingerprint) {
17967 switch (algo) {
17968 case enums.publicKey.rsaEncryptSign:
17969 case enums.publicKey.rsaEncrypt: {
17970 const { c } = sessionKeyParams;
17971 const { n, e } = publicKeyParams;
17972 const { d, p, q, u } = privateKeyParams;
17973 return publicKey.rsa.decrypt(c, n, e, d, p, q, u);
17974 }
17975 case enums.publicKey.elgamal: {
17976 const { c1, c2 } = sessionKeyParams;
17977 const p = publicKeyParams.p;
17978 const x = privateKeyParams.x;
17979 return publicKey.elgamal.decrypt(c1, c2, p, x);
17980 }
17981 case enums.publicKey.ecdh: {
17982 const { oid, Q, kdfParams } = publicKeyParams;
17983 const { d } = privateKeyParams;
17984 const { V, C } = sessionKeyParams;
17985 return publicKey.elliptic.ecdh.decrypt(
17986 oid, kdfParams, V, C.data, Q, d, fingerprint);
17987 }
17988 default:
17989 throw new Error('Invalid public key encryption algorithm.');
17990 }
17991}
17992
17993/**
17994 * Parse public key material in binary form to get the key parameters
17995 * @param {module:enums.publicKey} algo - The key algorithm
17996 * @param {Uint8Array} bytes - The key material to parse
17997 * @returns {{ read: Number, publicParams: Object }} Number of read bytes plus key parameters referenced by name.
17998 */
17999function parsePublicKeyParams(algo, bytes) {
18000 let read = 0;
18001 switch (algo) {
18002 case enums.publicKey.rsaEncrypt:
18003 case enums.publicKey.rsaEncryptSign:
18004 case enums.publicKey.rsaSign: {
18005 const n = util.readMPI(bytes.subarray(read)); read += n.length + 2;
18006 const e = util.readMPI(bytes.subarray(read)); read += e.length + 2;
18007 return { read, publicParams: { n, e } };
18008 }
18009 case enums.publicKey.dsa: {
18010 const p = util.readMPI(bytes.subarray(read)); read += p.length + 2;
18011 const q = util.readMPI(bytes.subarray(read)); read += q.length + 2;
18012 const g = util.readMPI(bytes.subarray(read)); read += g.length + 2;
18013 const y = util.readMPI(bytes.subarray(read)); read += y.length + 2;
18014 return { read, publicParams: { p, q, g, y } };
18015 }
18016 case enums.publicKey.elgamal: {
18017 const p = util.readMPI(bytes.subarray(read)); read += p.length + 2;
18018 const g = util.readMPI(bytes.subarray(read)); read += g.length + 2;
18019 const y = util.readMPI(bytes.subarray(read)); read += y.length + 2;
18020 return { read, publicParams: { p, g, y } };
18021 }
18022 case enums.publicKey.ecdsa: {
18023 const oid = new OID(); read += oid.read(bytes);
18024 const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
18025 return { read: read, publicParams: { oid, Q } };
18026 }
18027 case enums.publicKey.eddsa: {
18028 const oid = new OID(); read += oid.read(bytes);
18029 let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
18030 Q = util.leftPad(Q, 33);
18031 return { read: read, publicParams: { oid, Q } };
18032 }
18033 case enums.publicKey.ecdh: {
18034 const oid = new OID(); read += oid.read(bytes);
18035 const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
18036 const kdfParams = new KDFParams(); read += kdfParams.read(bytes.subarray(read));
18037 return { read: read, publicParams: { oid, Q, kdfParams } };
18038 }
18039 default:
18040 throw new Error('Invalid public key encryption algorithm.');
18041 }
18042}
18043
18044/**
18045 * Parse private key material in binary form to get the key parameters
18046 * @param {module:enums.publicKey} algo - The key algorithm
18047 * @param {Uint8Array} bytes - The key material to parse
18048 * @param {Object} publicParams - (ECC only) public params, needed to format some private params
18049 * @returns {{ read: Number, privateParams: Object }} Number of read bytes plus the key parameters referenced by name.
18050 */
18051function parsePrivateKeyParams(algo, bytes, publicParams) {
18052 let read = 0;
18053 switch (algo) {
18054 case enums.publicKey.rsaEncrypt:
18055 case enums.publicKey.rsaEncryptSign:
18056 case enums.publicKey.rsaSign: {
18057 const d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
18058 const p = util.readMPI(bytes.subarray(read)); read += p.length + 2;
18059 const q = util.readMPI(bytes.subarray(read)); read += q.length + 2;
18060 const u = util.readMPI(bytes.subarray(read)); read += u.length + 2;
18061 return { read, privateParams: { d, p, q, u } };
18062 }
18063 case enums.publicKey.dsa:
18064 case enums.publicKey.elgamal: {
18065 const x = util.readMPI(bytes.subarray(read)); read += x.length + 2;
18066 return { read, privateParams: { x } };
18067 }
18068 case enums.publicKey.ecdsa:
18069 case enums.publicKey.ecdh: {
18070 const curve = new Curve(publicParams.oid);
18071 let d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
18072 d = util.leftPad(d, curve.payloadSize);
18073 return { read, privateParams: { d } };
18074 }
18075 case enums.publicKey.eddsa: {
18076 let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
18077 seed = util.leftPad(seed, 32);
18078 return { read, privateParams: { seed } };
18079 }
18080 default:
18081 throw new Error('Invalid public key encryption algorithm.');
18082 }
18083}
18084
18085/** Returns the types comprising the encrypted session key of an algorithm
18086 * @param {module:enums.publicKey} algo - The key algorithm
18087 * @param {Uint8Array} bytes - The key material to parse
18088 * @returns {Object} The session key parameters referenced by name.
18089 */
18090function parseEncSessionKeyParams(algo, bytes) {
18091 let read = 0;
18092 switch (algo) {
18093 // Algorithm-Specific Fields for RSA encrypted session keys:
18094 // - MPI of RSA encrypted value m**e mod n.
18095 case enums.publicKey.rsaEncrypt:
18096 case enums.publicKey.rsaEncryptSign: {
18097 const c = util.readMPI(bytes.subarray(read));
18098 return { c };
18099 }
18100
18101 // Algorithm-Specific Fields for Elgamal encrypted session keys:
18102 // - MPI of Elgamal value g**k mod p
18103 // - MPI of Elgamal value m * y**k mod p
18104 case enums.publicKey.elgamal: {
18105 const c1 = util.readMPI(bytes.subarray(read)); read += c1.length + 2;
18106 const c2 = util.readMPI(bytes.subarray(read));
18107 return { c1, c2 };
18108 }
18109 // Algorithm-Specific Fields for ECDH encrypted session keys:
18110 // - MPI containing the ephemeral key used to establish the shared secret
18111 // - ECDH Symmetric Key
18112 case enums.publicKey.ecdh: {
18113 const V = util.readMPI(bytes.subarray(read)); read += V.length + 2;
18114 const C = new ECDHSymmetricKey(); C.read(bytes.subarray(read));
18115 return { V, C };
18116 }
18117 default:
18118 throw new Error('Invalid public key encryption algorithm.');
18119 }
18120}
18121
18122/**
18123 * Convert params to MPI and serializes them in the proper order
18124 * @param {module:enums.publicKey} algo - The public key algorithm
18125 * @param {Object} params - The key parameters indexed by name
18126 * @returns {Uint8Array} The array containing the MPIs.
18127 */
18128function serializeParams(algo, params) {
18129 const orderedParams = Object.keys(params).map(name => {
18130 const param = params[name];
18131 return util.isUint8Array(param) ? util.uint8ArrayToMpi(param) : param.write();
18132 });
18133 return util.concatUint8Array(orderedParams);
18134}
18135
18136/**
18137 * Generate algorithm-specific key parameters
18138 * @param {module:enums.publicKey} algo - The public key algorithm
18139 * @param {Integer} bits - Bit length for RSA keys
18140 * @param {module:type/oid} oid - Object identifier for ECC keys
18141 * @returns {{ publicParams: {Object}, privateParams: {Object} }} The parameters referenced by name.
18142 * @async
18143 */
18144function generateParams(algo, bits, oid) {
18145 switch (algo) {
18146 case enums.publicKey.rsaEncrypt:
18147 case enums.publicKey.rsaEncryptSign:
18148 case enums.publicKey.rsaSign: {
18149 return publicKey.rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({
18150 privateParams: { d, p, q, u },
18151 publicParams: { n, e }
18152 }));
18153 }
18154 case enums.publicKey.ecdsa:
18155 return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
18156 privateParams: { d: secret },
18157 publicParams: { oid: new OID(oid), Q }
18158 }));
18159 case enums.publicKey.eddsa:
18160 return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
18161 privateParams: { seed: secret },
18162 publicParams: { oid: new OID(oid), Q }
18163 }));
18164 case enums.publicKey.ecdh:
18165 return publicKey.elliptic.generate(oid).then(({ oid, Q, secret, hash, cipher }) => ({
18166 privateParams: { d: secret },
18167 publicParams: {
18168 oid: new OID(oid),
18169 Q,
18170 kdfParams: new KDFParams({ hash, cipher })
18171 }
18172 }));
18173 case enums.publicKey.dsa:
18174 case enums.publicKey.elgamal:
18175 throw new Error('Unsupported algorithm for key generation.');
18176 default:
18177 throw new Error('Invalid public key algorithm.');
18178 }
18179}
18180
18181/**
18182 * Validate algorithm-specific key parameters
18183 * @param {module:enums.publicKey} algo - The public key algorithm
18184 * @param {Object} publicParams - Algorithm-specific public key parameters
18185 * @param {Object} privateParams - Algorithm-specific private key parameters
18186 * @returns {Boolean} Whether the parameters are valid.
18187 * @async
18188 */
18189async function validateParams$6(algo, publicParams, privateParams) {
18190 if (!publicParams || !privateParams) {
18191 throw new Error('Missing key parameters');
18192 }
18193 switch (algo) {
18194 case enums.publicKey.rsaEncrypt:
18195 case enums.publicKey.rsaEncryptSign:
18196 case enums.publicKey.rsaSign: {
18197 const { n, e } = publicParams;
18198 const { d, p, q, u } = privateParams;
18199 return publicKey.rsa.validateParams(n, e, d, p, q, u);
18200 }
18201 case enums.publicKey.dsa: {
18202 const { p, q, g, y } = publicParams;
18203 const { x } = privateParams;
18204 return publicKey.dsa.validateParams(p, q, g, y, x);
18205 }
18206 case enums.publicKey.elgamal: {
18207 const { p, g, y } = publicParams;
18208 const { x } = privateParams;
18209 return publicKey.elgamal.validateParams(p, g, y, x);
18210 }
18211 case enums.publicKey.ecdsa:
18212 case enums.publicKey.ecdh: {
18213 const algoModule = publicKey.elliptic[enums.read(enums.publicKey, algo)];
18214 const { oid, Q } = publicParams;
18215 const { d } = privateParams;
18216 return algoModule.validateParams(oid, Q, d);
18217 }
18218 case enums.publicKey.eddsa: {
18219 const { oid, Q } = publicParams;
18220 const { seed } = privateParams;
18221 return publicKey.elliptic.eddsa.validateParams(oid, Q, seed);
18222 }
18223 default:
18224 throw new Error('Invalid public key algorithm.');
18225 }
18226}
18227
18228/**
18229 * Generates a random byte prefix for the specified algorithm
18230 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
18231 * @param {module:enums.symmetric} algo - Symmetric encryption algorithm
18232 * @returns {Uint8Array} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
18233 * @async
18234 */
18235async function getPrefixRandom(algo) {
18236 const prefixrandom = await getRandomBytes(cipher[algo].blockSize);
18237 const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
18238 return util.concat([prefixrandom, repeat]);
18239}
18240
18241/**
18242 * Generating a session key for the specified symmetric algorithm
18243 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
18244 * @param {module:enums.symmetric} algo - Symmetric encryption algorithm
18245 * @returns {Uint8Array} Random bytes as a string to be used as a key.
18246 * @async
18247 */
18248function generateSessionKey(algo) {
18249 return getRandomBytes(cipher[algo].keySize);
18250}
18251
18252var crypto$1 = /*#__PURE__*/Object.freeze({
18253 __proto__: null,
18254 publicKeyEncrypt: publicKeyEncrypt,
18255 publicKeyDecrypt: publicKeyDecrypt,
18256 parsePublicKeyParams: parsePublicKeyParams,
18257 parsePrivateKeyParams: parsePrivateKeyParams,
18258 parseEncSessionKeyParams: parseEncSessionKeyParams,
18259 serializeParams: serializeParams,
18260 generateParams: generateParams,
18261 validateParams: validateParams$6,
18262 getPrefixRandom: getPrefixRandom,
18263 generateSessionKey: generateSessionKey
18264});
18265
18266/**
18267 * @fileoverview Provides access to all cryptographic primitives used in OpenPGP.js
18268 * @see module:crypto/crypto
18269 * @see module:crypto/signature
18270 * @see module:crypto/public_key
18271 * @see module:crypto/cipher
18272 * @see module:crypto/random
18273 * @see module:crypto/hash
18274 * @module crypto
18275 * @private
18276 */
18277
18278// TODO move cfb and gcm to cipher
18279const mod = {
18280 /** @see module:crypto/cipher */
18281 cipher: cipher,
18282 /** @see module:crypto/hash */
18283 hash: hash,
18284 /** @see module:crypto/cfb */
18285 cfb: cfb,
18286 /** @see module:crypto/gcm */
18287 gcm: GCM,
18288 experimentalGcm: GCM,
18289 /** @see module:crypto/eax */
18290 eax: EAX,
18291 /** @see module:crypto/ocb */
18292 ocb: OCB,
18293 /** @see module:crypto/public_key */
18294 publicKey: publicKey,
18295 /** @see module:crypto/signature */
18296 signature: signature,
18297 /** @see module:crypto/random */
18298 random: random,
18299 /** @see module:crypto/pkcs1 */
18300 pkcs1: pkcs1,
18301 /** @see module:crypto/pkcs5 */
18302 pkcs5: pkcs5,
18303 /** @see module:crypto/aes_kw */
18304 aes_kw: aes_kw
18305};
18306
18307Object.assign(mod, crypto$1);
18308
18309var TYPED_OK = typeof Uint8Array !== "undefined" &&
18310 typeof Uint16Array !== "undefined" &&
18311 typeof Int32Array !== "undefined";
18312
18313
18314// reduce buffer size, avoiding mem copy
18315function shrinkBuf(buf, size) {
18316 if (buf.length === size) {
18317 return buf;
18318 }
18319 if (buf.subarray) {
18320 return buf.subarray(0, size);
18321 }
18322 buf.length = size;
18323 return buf;
18324}
18325
18326
18327const fnTyped = {
18328 arraySet: function (dest, src, src_offs, len, dest_offs) {
18329 if (src.subarray && dest.subarray) {
18330 dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
18331 return;
18332 }
18333 // Fallback to ordinary array
18334 for (let i = 0; i < len; i++) {
18335 dest[dest_offs + i] = src[src_offs + i];
18336 }
18337 },
18338 // Join array of chunks to single array.
18339 flattenChunks: function (chunks) {
18340 let i, l, len, pos, chunk;
18341
18342 // calculate data length
18343 len = 0;
18344 for (i = 0, l = chunks.length; i < l; i++) {
18345 len += chunks[i].length;
18346 }
18347
18348 // join chunks
18349 const result = new Uint8Array(len);
18350 pos = 0;
18351 for (i = 0, l = chunks.length; i < l; i++) {
18352 chunk = chunks[i];
18353 result.set(chunk, pos);
18354 pos += chunk.length;
18355 }
18356
18357 return result;
18358 }
18359};
18360
18361const fnUntyped = {
18362 arraySet: function (dest, src, src_offs, len, dest_offs) {
18363 for (let i = 0; i < len; i++) {
18364 dest[dest_offs + i] = src[src_offs + i];
18365 }
18366 },
18367 // Join array of chunks to single array.
18368 flattenChunks: function (chunks) {
18369 return [].concat.apply([], chunks);
18370 }
18371};
18372
18373
18374// Enable/Disable typed arrays use, for testing
18375//
18376
18377let Buf8 = TYPED_OK ? Uint8Array : Array;
18378let Buf16 = TYPED_OK ? Uint16Array : Array;
18379let Buf32 = TYPED_OK ? Int32Array : Array;
18380let flattenChunks = TYPED_OK ? fnTyped.flattenChunks : fnUntyped.flattenChunks;
18381let arraySet = TYPED_OK ? fnTyped.arraySet : fnUntyped.arraySet;
18382
18383// (C) 1995-2013 Jean-loup Gailly and Mark Adler
18384// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
18385//
18386// This software is provided 'as-is', without any express or implied
18387// warranty. In no event will the authors be held liable for any damages
18388// arising from the use of this software.
18389//
18390// Permission is granted to anyone to use this software for any purpose,
18391// including commercial applications, and to alter it and redistribute it
18392// freely, subject to the following restrictions:
18393//
18394// 1. The origin of this software must not be misrepresented; you must not
18395// claim that you wrote the original software. If you use this software
18396// in a product, an acknowledgment in the product documentation would be
18397// appreciated but is not required.
18398// 2. Altered source versions must be plainly marked as such, and must not be
18399// misrepresented as being the original software.
18400// 3. This notice may not be removed or altered from any source distribution.
18401
18402/* Allowed flush values; see deflate() and inflate() below for details */
18403const Z_NO_FLUSH = 0;
18404const Z_PARTIAL_FLUSH = 1;
18405const Z_SYNC_FLUSH = 2;
18406const Z_FULL_FLUSH = 3;
18407const Z_FINISH = 4;
18408const Z_BLOCK = 5;
18409const Z_TREES = 6;
18410
18411/* Return codes for the compression/decompression functions. Negative values
18412 * are errors, positive values are used for special but normal events.
18413 */
18414const Z_OK = 0;
18415const Z_STREAM_END = 1;
18416const Z_NEED_DICT = 2;
18417const Z_STREAM_ERROR = -2;
18418const Z_DATA_ERROR = -3;
18419//export const Z_MEM_ERROR = -4;
18420const Z_BUF_ERROR = -5;
18421const Z_DEFAULT_COMPRESSION = -1;
18422
18423
18424const Z_FILTERED = 1;
18425const Z_HUFFMAN_ONLY = 2;
18426const Z_RLE = 3;
18427const Z_FIXED = 4;
18428const Z_DEFAULT_STRATEGY = 0;
18429
18430/* Possible values of the data_type field (though see inflate()) */
18431const Z_BINARY = 0;
18432const Z_TEXT = 1;
18433//export const Z_ASCII = 1; // = Z_TEXT (deprecated)
18434const Z_UNKNOWN = 2;
18435
18436/* The deflate compression method */
18437const Z_DEFLATED = 8;
18438//export const Z_NULL = null // Use -1 or null inline, depending on var type
18439
18440/*============================================================================*/
18441
18442
18443function zero$1(buf) {
18444 let len = buf.length; while (--len >= 0) {
18445 buf[len] = 0;
18446 }
18447}
18448
18449// From zutil.h
18450
18451const STORED_BLOCK = 0;
18452const STATIC_TREES = 1;
18453const DYN_TREES = 2;
18454/* The three kinds of block type */
18455
18456const MIN_MATCH = 3;
18457const MAX_MATCH = 258;
18458/* The minimum and maximum match lengths */
18459
18460// From deflate.h
18461/* ===========================================================================
18462 * Internal compression state.
18463 */
18464
18465const LENGTH_CODES = 29;
18466/* number of length codes, not counting the special END_BLOCK code */
18467
18468const LITERALS = 256;
18469/* number of literal bytes 0..255 */
18470
18471const L_CODES = LITERALS + 1 + LENGTH_CODES;
18472/* number of Literal or Length codes, including the END_BLOCK code */
18473
18474const D_CODES = 30;
18475/* number of distance codes */
18476
18477const BL_CODES = 19;
18478/* number of codes used to transfer the bit lengths */
18479
18480const HEAP_SIZE = 2 * L_CODES + 1;
18481/* maximum heap size */
18482
18483const MAX_BITS = 15;
18484/* All codes must not exceed MAX_BITS bits */
18485
18486const Buf_size = 16;
18487/* size of bit buffer in bi_buf */
18488
18489
18490/* ===========================================================================
18491 * Constants
18492 */
18493
18494const MAX_BL_BITS = 7;
18495/* Bit length codes must not exceed MAX_BL_BITS bits */
18496
18497const END_BLOCK = 256;
18498/* end of block literal code */
18499
18500const REP_3_6 = 16;
18501/* repeat previous bit length 3-6 times (2 bits of repeat count) */
18502
18503const REPZ_3_10 = 17;
18504/* repeat a zero length 3-10 times (3 bits of repeat count) */
18505
18506const REPZ_11_138 = 18;
18507/* repeat a zero length 11-138 times (7 bits of repeat count) */
18508
18509/* eslint-disable comma-spacing,array-bracket-spacing */
18510const extra_lbits = /* extra bits for each length code */
18511 [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];
18512
18513const extra_dbits = /* extra bits for each distance code */
18514 [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];
18515
18516const extra_blbits = /* extra bits for each bit length code */
18517 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
18518
18519const bl_order =
18520 [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
18521/* eslint-enable comma-spacing,array-bracket-spacing */
18522
18523/* The lengths of the bit length codes are sent in order of decreasing
18524 * probability, to avoid transmitting the lengths for unused bit length codes.
18525 */
18526
18527/* ===========================================================================
18528 * Local data. These are initialized only once.
18529 */
18530
18531// We pre-fill arrays with 0 to avoid uninitialized gaps
18532
18533const DIST_CODE_LEN = 512; /* see definition of array dist_code below */
18534
18535// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
18536const static_ltree = new Array((L_CODES + 2) * 2);
18537zero$1(static_ltree);
18538/* The static literal tree. Since the bit lengths are imposed, there is no
18539 * need for the L_CODES extra codes used during heap construction. However
18540 * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
18541 * below).
18542 */
18543
18544const static_dtree = new Array(D_CODES * 2);
18545zero$1(static_dtree);
18546/* The static distance tree. (Actually a trivial tree since all codes use
18547 * 5 bits.)
18548 */
18549
18550const _dist_code = new Array(DIST_CODE_LEN);
18551zero$1(_dist_code);
18552/* Distance codes. The first 256 values correspond to the distances
18553 * 3 .. 258, the last 256 values correspond to the top 8 bits of
18554 * the 15 bit distances.
18555 */
18556
18557const _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
18558zero$1(_length_code);
18559/* length code for each normalized match length (0 == MIN_MATCH) */
18560
18561const base_length = new Array(LENGTH_CODES);
18562zero$1(base_length);
18563/* First normalized length for each code (0 = MIN_MATCH) */
18564
18565const base_dist = new Array(D_CODES);
18566zero$1(base_dist);
18567/* First normalized distance for each code (0 = distance of 1) */
18568
18569
18570function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
18571
18572 this.static_tree = static_tree; /* static tree or NULL */
18573 this.extra_bits = extra_bits; /* extra bits for each code or NULL */
18574 this.extra_base = extra_base; /* base index for extra_bits */
18575 this.elems = elems; /* max number of elements in the tree */
18576 this.max_length = max_length; /* max bit length for the codes */
18577
18578 // show if `static_tree` has data or dummy - needed for monomorphic objects
18579 this.has_stree = static_tree && static_tree.length;
18580}
18581
18582
18583let static_l_desc;
18584let static_d_desc;
18585let static_bl_desc;
18586
18587
18588function TreeDesc(dyn_tree, stat_desc) {
18589 this.dyn_tree = dyn_tree; /* the dynamic tree */
18590 this.max_code = 0; /* largest code with non zero frequency */
18591 this.stat_desc = stat_desc; /* the corresponding static tree */
18592}
18593
18594
18595
18596function d_code(dist) {
18597 return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
18598}
18599
18600
18601/* ===========================================================================
18602 * Output a short LSB first on the stream.
18603 * IN assertion: there is enough room in pendingBuf.
18604 */
18605function put_short(s, w) {
18606// put_byte(s, (uch)((w) & 0xff));
18607// put_byte(s, (uch)((ush)(w) >> 8));
18608 s.pending_buf[s.pending++] = w & 0xff;
18609 s.pending_buf[s.pending++] = w >>> 8 & 0xff;
18610}
18611
18612
18613/* ===========================================================================
18614 * Send a value on a given number of bits.
18615 * IN assertion: length <= 16 and value fits in length bits.
18616 */
18617function send_bits(s, value, length) {
18618 if (s.bi_valid > Buf_size - length) {
18619 s.bi_buf |= value << s.bi_valid & 0xffff;
18620 put_short(s, s.bi_buf);
18621 s.bi_buf = value >> Buf_size - s.bi_valid;
18622 s.bi_valid += length - Buf_size;
18623 } else {
18624 s.bi_buf |= value << s.bi_valid & 0xffff;
18625 s.bi_valid += length;
18626 }
18627}
18628
18629
18630function send_code(s, c, tree) {
18631 send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
18632}
18633
18634
18635/* ===========================================================================
18636 * Reverse the first len bits of a code, using straightforward code (a faster
18637 * method would use a table)
18638 * IN assertion: 1 <= len <= 15
18639 */
18640function bi_reverse(code, len) {
18641 let res = 0;
18642 do {
18643 res |= code & 1;
18644 code >>>= 1;
18645 res <<= 1;
18646 } while (--len > 0);
18647 return res >>> 1;
18648}
18649
18650
18651/* ===========================================================================
18652 * Flush the bit buffer, keeping at most 7 bits in it.
18653 */
18654function bi_flush(s) {
18655 if (s.bi_valid === 16) {
18656 put_short(s, s.bi_buf);
18657 s.bi_buf = 0;
18658 s.bi_valid = 0;
18659
18660 } else if (s.bi_valid >= 8) {
18661 s.pending_buf[s.pending++] = s.bi_buf & 0xff;
18662 s.bi_buf >>= 8;
18663 s.bi_valid -= 8;
18664 }
18665}
18666
18667
18668/* ===========================================================================
18669 * Compute the optimal bit lengths for a tree and update the total bit length
18670 * for the current block.
18671 * IN assertion: the fields freq and dad are set, heap[heap_max] and
18672 * above are the tree nodes sorted by increasing frequency.
18673 * OUT assertions: the field len is set to the optimal bit length, the
18674 * array bl_count contains the frequencies for each bit length.
18675 * The length opt_len is updated; static_len is also updated if stree is
18676 * not null.
18677 */
18678function gen_bitlen(s, desc)
18679// deflate_state *s;
18680// tree_desc *desc; /* the tree descriptor */
18681{
18682 const tree = desc.dyn_tree;
18683 const max_code = desc.max_code;
18684 const stree = desc.stat_desc.static_tree;
18685 const has_stree = desc.stat_desc.has_stree;
18686 const extra = desc.stat_desc.extra_bits;
18687 const base = desc.stat_desc.extra_base;
18688 const max_length = desc.stat_desc.max_length;
18689 let h; /* heap index */
18690 let n, m; /* iterate over the tree elements */
18691 let bits; /* bit length */
18692 let xbits; /* extra bits */
18693 let f; /* frequency */
18694 let overflow = 0; /* number of elements with bit length too large */
18695
18696 for (bits = 0; bits <= MAX_BITS; bits++) {
18697 s.bl_count[bits] = 0;
18698 }
18699
18700 /* In a first pass, compute the optimal bit lengths (which may
18701 * overflow in the case of the bit length tree).
18702 */
18703 tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
18704
18705 for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
18706 n = s.heap[h];
18707 bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
18708 if (bits > max_length) {
18709 bits = max_length;
18710 overflow++;
18711 }
18712 tree[n * 2 + 1]/*.Len*/ = bits;
18713 /* We overwrite tree[n].Dad which is no longer needed */
18714
18715 if (n > max_code) {
18716 continue;
18717 } /* not a leaf node */
18718
18719 s.bl_count[bits]++;
18720 xbits = 0;
18721 if (n >= base) {
18722 xbits = extra[n - base];
18723 }
18724 f = tree[n * 2]/*.Freq*/;
18725 s.opt_len += f * (bits + xbits);
18726 if (has_stree) {
18727 s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
18728 }
18729 }
18730 if (overflow === 0) {
18731 return;
18732 }
18733
18734 // Trace((stderr,"\nbit length overflow\n"));
18735 /* This happens for example on obj2 and pic of the Calgary corpus */
18736
18737 /* Find the first bit length which could increase: */
18738 do {
18739 bits = max_length - 1;
18740 while (s.bl_count[bits] === 0) {
18741 bits--;
18742 }
18743 s.bl_count[bits]--; /* move one leaf down the tree */
18744 s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
18745 s.bl_count[max_length]--;
18746 /* The brother of the overflow item also moves one step up,
18747 * but this does not affect bl_count[max_length]
18748 */
18749 overflow -= 2;
18750 } while (overflow > 0);
18751
18752 /* Now recompute all bit lengths, scanning in increasing frequency.
18753 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
18754 * lengths instead of fixing only the wrong ones. This idea is taken
18755 * from 'ar' written by Haruhiko Okumura.)
18756 */
18757 for (bits = max_length; bits !== 0; bits--) {
18758 n = s.bl_count[bits];
18759 while (n !== 0) {
18760 m = s.heap[--h];
18761 if (m > max_code) {
18762 continue;
18763 }
18764 if (tree[m * 2 + 1]/*.Len*/ !== bits) {
18765 // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
18766 s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
18767 tree[m * 2 + 1]/*.Len*/ = bits;
18768 }
18769 n--;
18770 }
18771 }
18772}
18773
18774
18775/* ===========================================================================
18776 * Generate the codes for a given tree and bit counts (which need not be
18777 * optimal).
18778 * IN assertion: the array bl_count contains the bit length statistics for
18779 * the given tree and the field len is set for all tree elements.
18780 * OUT assertion: the field code is set for all tree elements of non
18781 * zero code length.
18782 */
18783function gen_codes(tree, max_code, bl_count)
18784// ct_data *tree; /* the tree to decorate */
18785// int max_code; /* largest code with non zero frequency */
18786// ushf *bl_count; /* number of codes at each bit length */
18787{
18788 const next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
18789 let code = 0; /* running code value */
18790 let bits; /* bit index */
18791 let n; /* code index */
18792
18793 /* The distribution counts are first used to generate the code values
18794 * without bit reversal.
18795 */
18796 for (bits = 1; bits <= MAX_BITS; bits++) {
18797 next_code[bits] = code = code + bl_count[bits - 1] << 1;
18798 }
18799 /* Check that the bit counts in bl_count are consistent. The last code
18800 * must be all ones.
18801 */
18802 //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
18803 // "inconsistent bit counts");
18804 //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
18805
18806 for (n = 0; n <= max_code; n++) {
18807 const len = tree[n * 2 + 1]/*.Len*/;
18808 if (len === 0) {
18809 continue;
18810 }
18811 /* Now reverse the bits */
18812 tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
18813
18814 //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
18815 // n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
18816 }
18817}
18818
18819
18820/* ===========================================================================
18821 * Initialize the various 'constant' tables.
18822 */
18823function tr_static_init() {
18824 let n; /* iterates over tree elements */
18825 let bits; /* bit counter */
18826 let length; /* length value */
18827 let code; /* code value */
18828 let dist; /* distance index */
18829 const bl_count = new Array(MAX_BITS + 1);
18830 /* number of codes at each bit length for an optimal tree */
18831
18832 // do check in _tr_init()
18833 //if (static_init_done) return;
18834
18835 /* For some embedded targets, global variables are not initialized: */
18836 /*#ifdef NO_INIT_GLOBAL_POINTERS
18837 static_l_desc.static_tree = static_ltree;
18838 static_l_desc.extra_bits = extra_lbits;
18839 static_d_desc.static_tree = static_dtree;
18840 static_d_desc.extra_bits = extra_dbits;
18841 static_bl_desc.extra_bits = extra_blbits;
18842#endif*/
18843
18844 /* Initialize the mapping length (0..255) -> length code (0..28) */
18845 length = 0;
18846 for (code = 0; code < LENGTH_CODES - 1; code++) {
18847 base_length[code] = length;
18848 for (n = 0; n < 1 << extra_lbits[code]; n++) {
18849 _length_code[length++] = code;
18850 }
18851 }
18852 //Assert (length == 256, "tr_static_init: length != 256");
18853 /* Note that the length 255 (match length 258) can be represented
18854 * in two different ways: code 284 + 5 bits or code 285, so we
18855 * overwrite length_code[255] to use the best encoding:
18856 */
18857 _length_code[length - 1] = code;
18858
18859 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
18860 dist = 0;
18861 for (code = 0; code < 16; code++) {
18862 base_dist[code] = dist;
18863 for (n = 0; n < 1 << extra_dbits[code]; n++) {
18864 _dist_code[dist++] = code;
18865 }
18866 }
18867 //Assert (dist == 256, "tr_static_init: dist != 256");
18868 dist >>= 7; /* from now on, all distances are divided by 128 */
18869 for (; code < D_CODES; code++) {
18870 base_dist[code] = dist << 7;
18871 for (n = 0; n < 1 << extra_dbits[code] - 7; n++) {
18872 _dist_code[256 + dist++] = code;
18873 }
18874 }
18875 //Assert (dist == 256, "tr_static_init: 256+dist != 512");
18876
18877 /* Construct the codes of the static literal tree */
18878 for (bits = 0; bits <= MAX_BITS; bits++) {
18879 bl_count[bits] = 0;
18880 }
18881
18882 n = 0;
18883 while (n <= 143) {
18884 static_ltree[n * 2 + 1]/*.Len*/ = 8;
18885 n++;
18886 bl_count[8]++;
18887 }
18888 while (n <= 255) {
18889 static_ltree[n * 2 + 1]/*.Len*/ = 9;
18890 n++;
18891 bl_count[9]++;
18892 }
18893 while (n <= 279) {
18894 static_ltree[n * 2 + 1]/*.Len*/ = 7;
18895 n++;
18896 bl_count[7]++;
18897 }
18898 while (n <= 287) {
18899 static_ltree[n * 2 + 1]/*.Len*/ = 8;
18900 n++;
18901 bl_count[8]++;
18902 }
18903 /* Codes 286 and 287 do not exist, but we must include them in the
18904 * tree construction to get a canonical Huffman tree (longest code
18905 * all ones)
18906 */
18907 gen_codes(static_ltree, L_CODES + 1, bl_count);
18908
18909 /* The static distance tree is trivial: */
18910 for (n = 0; n < D_CODES; n++) {
18911 static_dtree[n * 2 + 1]/*.Len*/ = 5;
18912 static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
18913 }
18914
18915 // Now data ready and we can init static trees
18916 static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
18917 static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS);
18918 static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS);
18919
18920 //static_init_done = true;
18921}
18922
18923
18924/* ===========================================================================
18925 * Initialize a new block.
18926 */
18927function init_block(s) {
18928 let n; /* iterates over tree elements */
18929
18930 /* Initialize the trees. */
18931 for (n = 0; n < L_CODES; n++) {
18932 s.dyn_ltree[n * 2]/*.Freq*/ = 0;
18933 }
18934 for (n = 0; n < D_CODES; n++) {
18935 s.dyn_dtree[n * 2]/*.Freq*/ = 0;
18936 }
18937 for (n = 0; n < BL_CODES; n++) {
18938 s.bl_tree[n * 2]/*.Freq*/ = 0;
18939 }
18940
18941 s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
18942 s.opt_len = s.static_len = 0;
18943 s.last_lit = s.matches = 0;
18944}
18945
18946
18947/* ===========================================================================
18948 * Flush the bit buffer and align the output on a byte boundary
18949 */
18950function bi_windup(s) {
18951 if (s.bi_valid > 8) {
18952 put_short(s, s.bi_buf);
18953 } else if (s.bi_valid > 0) {
18954 //put_byte(s, (Byte)s->bi_buf);
18955 s.pending_buf[s.pending++] = s.bi_buf;
18956 }
18957 s.bi_buf = 0;
18958 s.bi_valid = 0;
18959}
18960
18961/* ===========================================================================
18962 * Copy a stored block, storing first the length and its
18963 * one's complement if requested.
18964 */
18965function copy_block(s, buf, len, header)
18966//DeflateState *s;
18967//charf *buf; /* the input data */
18968//unsigned len; /* its length */
18969//int header; /* true if block header must be written */
18970{
18971 bi_windup(s); /* align on byte boundary */
18972
18973 if (header) {
18974 put_short(s, len);
18975 put_short(s, ~len);
18976 }
18977 // while (len--) {
18978 // put_byte(s, *buf++);
18979 // }
18980 arraySet(s.pending_buf, s.window, buf, len, s.pending);
18981 s.pending += len;
18982}
18983
18984/* ===========================================================================
18985 * Compares to subtrees, using the tree depth as tie breaker when
18986 * the subtrees have equal frequency. This minimizes the worst case length.
18987 */
18988function smaller(tree, n, m, depth) {
18989 const _n2 = n * 2;
18990 const _m2 = m * 2;
18991 return tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
18992 tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m];
18993}
18994
18995/* ===========================================================================
18996 * Restore the heap property by moving down the tree starting at node k,
18997 * exchanging a node with the smallest of its two sons if necessary, stopping
18998 * when the heap property is re-established (each father smaller than its
18999 * two sons).
19000 */
19001function pqdownheap(s, tree, k)
19002// deflate_state *s;
19003// ct_data *tree; /* the tree to restore */
19004// int k; /* node to move down */
19005{
19006 const v = s.heap[k];
19007 let j = k << 1; /* left son of k */
19008 while (j <= s.heap_len) {
19009 /* Set j to the smallest of the two sons: */
19010 if (j < s.heap_len &&
19011 smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
19012 j++;
19013 }
19014 /* Exit if v is smaller than both sons */
19015 if (smaller(tree, v, s.heap[j], s.depth)) {
19016 break;
19017 }
19018
19019 /* Exchange v with the smallest son */
19020 s.heap[k] = s.heap[j];
19021 k = j;
19022
19023 /* And continue down the tree, setting j to the left son of k */
19024 j <<= 1;
19025 }
19026 s.heap[k] = v;
19027}
19028
19029
19030// inlined manually
19031// var SMALLEST = 1;
19032
19033/* ===========================================================================
19034 * Send the block data compressed using the given Huffman trees
19035 */
19036function compress_block(s, ltree, dtree)
19037// deflate_state *s;
19038// const ct_data *ltree; /* literal tree */
19039// const ct_data *dtree; /* distance tree */
19040{
19041 let dist; /* distance of matched string */
19042 let lc; /* match length or unmatched char (if dist == 0) */
19043 let lx = 0; /* running index in l_buf */
19044 let code; /* the code to send */
19045 let extra; /* number of extra bits to send */
19046
19047 if (s.last_lit !== 0) {
19048 do {
19049 dist = s.pending_buf[s.d_buf + lx * 2] << 8 | s.pending_buf[s.d_buf + lx * 2 + 1];
19050 lc = s.pending_buf[s.l_buf + lx];
19051 lx++;
19052
19053 if (dist === 0) {
19054 send_code(s, lc, ltree); /* send a literal byte */
19055 //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
19056 } else {
19057 /* Here, lc is the match length - MIN_MATCH */
19058 code = _length_code[lc];
19059 send_code(s, code + LITERALS + 1, ltree); /* send the length code */
19060 extra = extra_lbits[code];
19061 if (extra !== 0) {
19062 lc -= base_length[code];
19063 send_bits(s, lc, extra); /* send the extra length bits */
19064 }
19065 dist--; /* dist is now the match distance - 1 */
19066 code = d_code(dist);
19067 //Assert (code < D_CODES, "bad d_code");
19068
19069 send_code(s, code, dtree); /* send the distance code */
19070 extra = extra_dbits[code];
19071 if (extra !== 0) {
19072 dist -= base_dist[code];
19073 send_bits(s, dist, extra); /* send the extra distance bits */
19074 }
19075 } /* literal or match pair ? */
19076
19077 /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
19078 //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
19079 // "pendingBuf overflow");
19080
19081 } while (lx < s.last_lit);
19082 }
19083
19084 send_code(s, END_BLOCK, ltree);
19085}
19086
19087
19088/* ===========================================================================
19089 * Construct one Huffman tree and assigns the code bit strings and lengths.
19090 * Update the total bit length for the current block.
19091 * IN assertion: the field freq is set for all tree elements.
19092 * OUT assertions: the fields len and code are set to the optimal bit length
19093 * and corresponding code. The length opt_len is updated; static_len is
19094 * also updated if stree is not null. The field max_code is set.
19095 */
19096function build_tree(s, desc)
19097// deflate_state *s;
19098// tree_desc *desc; /* the tree descriptor */
19099{
19100 const tree = desc.dyn_tree;
19101 const stree = desc.stat_desc.static_tree;
19102 const has_stree = desc.stat_desc.has_stree;
19103 const elems = desc.stat_desc.elems;
19104 let n, m; /* iterate over heap elements */
19105 let max_code = -1; /* largest code with non zero frequency */
19106 let node; /* new node being created */
19107
19108 /* Construct the initial heap, with least frequent element in
19109 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
19110 * heap[0] is not used.
19111 */
19112 s.heap_len = 0;
19113 s.heap_max = HEAP_SIZE;
19114
19115 for (n = 0; n < elems; n++) {
19116 if (tree[n * 2]/*.Freq*/ !== 0) {
19117 s.heap[++s.heap_len] = max_code = n;
19118 s.depth[n] = 0;
19119
19120 } else {
19121 tree[n * 2 + 1]/*.Len*/ = 0;
19122 }
19123 }
19124
19125 /* The pkzip format requires that at least one distance code exists,
19126 * and that at least one bit should be sent even if there is only one
19127 * possible code. So to avoid special checks later on we force at least
19128 * two codes of non zero frequency.
19129 */
19130 while (s.heap_len < 2) {
19131 node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
19132 tree[node * 2]/*.Freq*/ = 1;
19133 s.depth[node] = 0;
19134 s.opt_len--;
19135
19136 if (has_stree) {
19137 s.static_len -= stree[node * 2 + 1]/*.Len*/;
19138 }
19139 /* node is 0 or 1 so it does not have extra bits */
19140 }
19141 desc.max_code = max_code;
19142
19143 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
19144 * establish sub-heaps of increasing lengths:
19145 */
19146 for (n = s.heap_len >> 1/*int /2*/; n >= 1; n--) {
19147 pqdownheap(s, tree, n);
19148 }
19149
19150 /* Construct the Huffman tree by repeatedly combining the least two
19151 * frequent nodes.
19152 */
19153 node = elems; /* next internal node of the tree */
19154 do {
19155 //pqremove(s, tree, n); /* n = node of least frequency */
19156 /*** pqremove ***/
19157 n = s.heap[1/*SMALLEST*/];
19158 s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
19159 pqdownheap(s, tree, 1/*SMALLEST*/);
19160 /***/
19161
19162 m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
19163
19164 s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
19165 s.heap[--s.heap_max] = m;
19166
19167 /* Create a new node father of n and m */
19168 tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
19169 s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
19170 tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
19171
19172 /* and insert the new node in the heap */
19173 s.heap[1/*SMALLEST*/] = node++;
19174 pqdownheap(s, tree, 1/*SMALLEST*/);
19175
19176 } while (s.heap_len >= 2);
19177
19178 s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
19179
19180 /* At this point, the fields freq and dad are set. We can now
19181 * generate the bit lengths.
19182 */
19183 gen_bitlen(s, desc);
19184
19185 /* The field len is now set, we can generate the bit codes */
19186 gen_codes(tree, max_code, s.bl_count);
19187}
19188
19189
19190/* ===========================================================================
19191 * Scan a literal or distance tree to determine the frequencies of the codes
19192 * in the bit length tree.
19193 */
19194function scan_tree(s, tree, max_code)
19195// deflate_state *s;
19196// ct_data *tree; /* the tree to be scanned */
19197// int max_code; /* and its largest code of non zero frequency */
19198{
19199 let n; /* iterates over all tree elements */
19200 let prevlen = -1; /* last emitted length */
19201 let curlen; /* length of current code */
19202
19203 let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
19204
19205 let count = 0; /* repeat count of the current code */
19206 let max_count = 7; /* max repeat count */
19207 let min_count = 4; /* min repeat count */
19208
19209 if (nextlen === 0) {
19210 max_count = 138;
19211 min_count = 3;
19212 }
19213 tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
19214
19215 for (n = 0; n <= max_code; n++) {
19216 curlen = nextlen;
19217 nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
19218
19219 if (++count < max_count && curlen === nextlen) {
19220 continue;
19221
19222 } else if (count < min_count) {
19223 s.bl_tree[curlen * 2]/*.Freq*/ += count;
19224
19225 } else if (curlen !== 0) {
19226
19227 if (curlen !== prevlen) {
19228 s.bl_tree[curlen * 2]/*.Freq*/++;
19229 }
19230 s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
19231
19232 } else if (count <= 10) {
19233 s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
19234
19235 } else {
19236 s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
19237 }
19238
19239 count = 0;
19240 prevlen = curlen;
19241
19242 if (nextlen === 0) {
19243 max_count = 138;
19244 min_count = 3;
19245
19246 } else if (curlen === nextlen) {
19247 max_count = 6;
19248 min_count = 3;
19249
19250 } else {
19251 max_count = 7;
19252 min_count = 4;
19253 }
19254 }
19255}
19256
19257
19258/* ===========================================================================
19259 * Send a literal or distance tree in compressed form, using the codes in
19260 * bl_tree.
19261 */
19262function send_tree(s, tree, max_code)
19263// deflate_state *s;
19264// ct_data *tree; /* the tree to be scanned */
19265// int max_code; /* and its largest code of non zero frequency */
19266{
19267 let n; /* iterates over all tree elements */
19268 let prevlen = -1; /* last emitted length */
19269 let curlen; /* length of current code */
19270
19271 let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
19272
19273 let count = 0; /* repeat count of the current code */
19274 let max_count = 7; /* max repeat count */
19275 let min_count = 4; /* min repeat count */
19276
19277 /* tree[max_code+1].Len = -1; */ /* guard already set */
19278 if (nextlen === 0) {
19279 max_count = 138;
19280 min_count = 3;
19281 }
19282
19283 for (n = 0; n <= max_code; n++) {
19284 curlen = nextlen;
19285 nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
19286
19287 if (++count < max_count && curlen === nextlen) {
19288 continue;
19289
19290 } else if (count < min_count) {
19291 do {
19292 send_code(s, curlen, s.bl_tree);
19293 } while (--count !== 0);
19294
19295 } else if (curlen !== 0) {
19296 if (curlen !== prevlen) {
19297 send_code(s, curlen, s.bl_tree);
19298 count--;
19299 }
19300 //Assert(count >= 3 && count <= 6, " 3_6?");
19301 send_code(s, REP_3_6, s.bl_tree);
19302 send_bits(s, count - 3, 2);
19303
19304 } else if (count <= 10) {
19305 send_code(s, REPZ_3_10, s.bl_tree);
19306 send_bits(s, count - 3, 3);
19307
19308 } else {
19309 send_code(s, REPZ_11_138, s.bl_tree);
19310 send_bits(s, count - 11, 7);
19311 }
19312
19313 count = 0;
19314 prevlen = curlen;
19315 if (nextlen === 0) {
19316 max_count = 138;
19317 min_count = 3;
19318
19319 } else if (curlen === nextlen) {
19320 max_count = 6;
19321 min_count = 3;
19322
19323 } else {
19324 max_count = 7;
19325 min_count = 4;
19326 }
19327 }
19328}
19329
19330
19331/* ===========================================================================
19332 * Construct the Huffman tree for the bit lengths and return the index in
19333 * bl_order of the last bit length code to send.
19334 */
19335function build_bl_tree(s) {
19336 let max_blindex; /* index of last bit length code of non zero freq */
19337
19338 /* Determine the bit length frequencies for literal and distance trees */
19339 scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
19340 scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
19341
19342 /* Build the bit length tree: */
19343 build_tree(s, s.bl_desc);
19344 /* opt_len now includes the length of the tree representations, except
19345 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
19346 */
19347
19348 /* Determine the number of bit length codes to send. The pkzip format
19349 * requires that at least 4 bit length codes be sent. (appnote.txt says
19350 * 3 but the actual value used is 4.)
19351 */
19352 for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
19353 if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
19354 break;
19355 }
19356 }
19357 /* Update opt_len to include the bit length tree and counts */
19358 s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
19359 //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
19360 // s->opt_len, s->static_len));
19361
19362 return max_blindex;
19363}
19364
19365
19366/* ===========================================================================
19367 * Send the header for a block using dynamic Huffman trees: the counts, the
19368 * lengths of the bit length codes, the literal tree and the distance tree.
19369 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
19370 */
19371function send_all_trees(s, lcodes, dcodes, blcodes)
19372// deflate_state *s;
19373// int lcodes, dcodes, blcodes; /* number of codes for each tree */
19374{
19375 let rank; /* index in bl_order */
19376
19377 //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
19378 //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
19379 // "too many codes");
19380 //Tracev((stderr, "\nbl counts: "));
19381 send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
19382 send_bits(s, dcodes - 1, 5);
19383 send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
19384 for (rank = 0; rank < blcodes; rank++) {
19385 //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
19386 send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
19387 }
19388 //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
19389
19390 send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
19391 //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
19392
19393 send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
19394 //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
19395}
19396
19397
19398/* ===========================================================================
19399 * Check if the data type is TEXT or BINARY, using the following algorithm:
19400 * - TEXT if the two conditions below are satisfied:
19401 * a) There are no non-portable control characters belonging to the
19402 * "black list" (0..6, 14..25, 28..31).
19403 * b) There is at least one printable character belonging to the
19404 * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
19405 * - BINARY otherwise.
19406 * - The following partially-portable control characters form a
19407 * "gray list" that is ignored in this detection algorithm:
19408 * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
19409 * IN assertion: the fields Freq of dyn_ltree are set.
19410 */
19411function detect_data_type(s) {
19412 /* black_mask is the bit mask of black-listed bytes
19413 * set bits 0..6, 14..25, and 28..31
19414 * 0xf3ffc07f = binary 11110011111111111100000001111111
19415 */
19416 let black_mask = 0xf3ffc07f;
19417 let n;
19418
19419 /* Check for non-textual ("black-listed") bytes. */
19420 for (n = 0; n <= 31; n++, black_mask >>>= 1) {
19421 if (black_mask & 1 && s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
19422 return Z_BINARY;
19423 }
19424 }
19425
19426 /* Check for textual ("white-listed") bytes. */
19427 if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
19428 s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
19429 return Z_TEXT;
19430 }
19431 for (n = 32; n < LITERALS; n++) {
19432 if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
19433 return Z_TEXT;
19434 }
19435 }
19436
19437 /* There are no "black-listed" or "white-listed" bytes:
19438 * this stream either is empty or has tolerated ("gray-listed") bytes only.
19439 */
19440 return Z_BINARY;
19441}
19442
19443
19444let static_init_done = false;
19445
19446/* ===========================================================================
19447 * Initialize the tree data structures for a new zlib stream.
19448 */
19449function _tr_init(s) {
19450
19451 if (!static_init_done) {
19452 tr_static_init();
19453 static_init_done = true;
19454 }
19455
19456 s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);
19457 s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);
19458 s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
19459
19460 s.bi_buf = 0;
19461 s.bi_valid = 0;
19462
19463 /* Initialize the first block of the first file: */
19464 init_block(s);
19465}
19466
19467
19468/* ===========================================================================
19469 * Send a stored block
19470 */
19471function _tr_stored_block(s, buf, stored_len, last)
19472//DeflateState *s;
19473//charf *buf; /* input block */
19474//ulg stored_len; /* length of input block */
19475//int last; /* one if this is the last block for a file */
19476{
19477 send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */
19478 copy_block(s, buf, stored_len, true); /* with header */
19479}
19480
19481
19482/* ===========================================================================
19483 * Send one empty static block to give enough lookahead for inflate.
19484 * This takes 10 bits, of which 7 may remain in the bit buffer.
19485 */
19486function _tr_align(s) {
19487 send_bits(s, STATIC_TREES << 1, 3);
19488 send_code(s, END_BLOCK, static_ltree);
19489 bi_flush(s);
19490}
19491
19492
19493/* ===========================================================================
19494 * Determine the best encoding for the current block: dynamic trees, static
19495 * trees or store, and output the encoded block to the zip file.
19496 */
19497function _tr_flush_block(s, buf, stored_len, last)
19498//DeflateState *s;
19499//charf *buf; /* input block, or NULL if too old */
19500//ulg stored_len; /* length of input block */
19501//int last; /* one if this is the last block for a file */
19502{
19503 let opt_lenb, static_lenb; /* opt_len and static_len in bytes */
19504 let max_blindex = 0; /* index of last bit length code of non zero freq */
19505
19506 /* Build the Huffman trees unless a stored block is forced */
19507 if (s.level > 0) {
19508
19509 /* Check if the file is binary or text */
19510 if (s.strm.data_type === Z_UNKNOWN) {
19511 s.strm.data_type = detect_data_type(s);
19512 }
19513
19514 /* Construct the literal and distance trees */
19515 build_tree(s, s.l_desc);
19516 // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
19517 // s->static_len));
19518
19519 build_tree(s, s.d_desc);
19520 // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
19521 // s->static_len));
19522 /* At this point, opt_len and static_len are the total bit lengths of
19523 * the compressed block data, excluding the tree representations.
19524 */
19525
19526 /* Build the bit length tree for the above two trees, and get the index
19527 * in bl_order of the last bit length code to send.
19528 */
19529 max_blindex = build_bl_tree(s);
19530
19531 /* Determine the best encoding. Compute the block lengths in bytes. */
19532 opt_lenb = s.opt_len + 3 + 7 >>> 3;
19533 static_lenb = s.static_len + 3 + 7 >>> 3;
19534
19535 // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
19536 // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
19537 // s->last_lit));
19538
19539 if (static_lenb <= opt_lenb) {
19540 opt_lenb = static_lenb;
19541 }
19542
19543 } else {
19544 // Assert(buf != (char*)0, "lost buf");
19545 opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
19546 }
19547
19548 if (stored_len + 4 <= opt_lenb && buf !== -1) {
19549 /* 4: two words for the lengths */
19550
19551 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
19552 * Otherwise we can't have processed more than WSIZE input bytes since
19553 * the last block flush, because compression would have been
19554 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
19555 * transform a block into a stored block.
19556 */
19557 _tr_stored_block(s, buf, stored_len, last);
19558
19559 } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
19560
19561 send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
19562 compress_block(s, static_ltree, static_dtree);
19563
19564 } else {
19565 send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
19566 send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
19567 compress_block(s, s.dyn_ltree, s.dyn_dtree);
19568 }
19569 // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
19570 /* The above check is made mod 2^32, for files larger than 512 MB
19571 * and uLong implemented on 32 bits.
19572 */
19573 init_block(s);
19574
19575 if (last) {
19576 bi_windup(s);
19577 }
19578 // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
19579 // s->compressed_len-7*last));
19580}
19581
19582/* ===========================================================================
19583 * Save the match info and tally the frequency counts. Return true if
19584 * the current block must be flushed.
19585 */
19586function _tr_tally(s, dist, lc)
19587// deflate_state *s;
19588// unsigned dist; /* distance of matched string */
19589// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
19590{
19591 //var out_length, in_length, dcode;
19592
19593 s.pending_buf[s.d_buf + s.last_lit * 2] = dist >>> 8 & 0xff;
19594 s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
19595
19596 s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
19597 s.last_lit++;
19598
19599 if (dist === 0) {
19600 /* lc is the unmatched char */
19601 s.dyn_ltree[lc * 2]/*.Freq*/++;
19602 } else {
19603 s.matches++;
19604 /* Here, lc is the match length - MIN_MATCH */
19605 dist--; /* dist = match distance - 1 */
19606 //Assert((ush)dist < (ush)MAX_DIST(s) &&
19607 // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
19608 // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
19609
19610 s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
19611 s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
19612 }
19613
19614 // (!) This block is disabled in zlib defaults,
19615 // don't enable it for binary compatibility
19616
19617 //#ifdef TRUNCATE_BLOCK
19618 // /* Try to guess if it is profitable to stop the current block here */
19619 // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
19620 // /* Compute an upper bound for the compressed length */
19621 // out_length = s.last_lit*8;
19622 // in_length = s.strstart - s.block_start;
19623 //
19624 // for (dcode = 0; dcode < D_CODES; dcode++) {
19625 // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
19626 // }
19627 // out_length >>>= 3;
19628 // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
19629 // // s->last_lit, in_length, out_length,
19630 // // 100L - out_length*100L/in_length));
19631 // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
19632 // return true;
19633 // }
19634 // }
19635 //#endif
19636
19637 return s.last_lit === s.lit_bufsize - 1;
19638 /* We avoid equality with lit_bufsize because of wraparound at 64K
19639 * on 16 bit machines and because stored blocks are restricted to
19640 * 64K-1 bytes.
19641 */
19642}
19643
19644// Note: adler32 takes 12% for level 0 and 2% for level 6.
19645// It isn't worth it to make additional optimizations as in original.
19646// Small size is preferable.
19647
19648// (C) 1995-2013 Jean-loup Gailly and Mark Adler
19649// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
19650//
19651// This software is provided 'as-is', without any express or implied
19652// warranty. In no event will the authors be held liable for any damages
19653// arising from the use of this software.
19654//
19655// Permission is granted to anyone to use this software for any purpose,
19656// including commercial applications, and to alter it and redistribute it
19657// freely, subject to the following restrictions:
19658//
19659// 1. The origin of this software must not be misrepresented; you must not
19660// claim that you wrote the original software. If you use this software
19661// in a product, an acknowledgment in the product documentation would be
19662// appreciated but is not required.
19663// 2. Altered source versions must be plainly marked as such, and must not be
19664// misrepresented as being the original software.
19665// 3. This notice may not be removed or altered from any source distribution.
19666
19667function adler32(adler, buf, len, pos) {
19668 let s1 = adler & 0xffff |0,
19669 s2 = adler >>> 16 & 0xffff |0,
19670 n = 0;
19671
19672 while (len !== 0) {
19673 // Set limit ~ twice less than 5552, to keep
19674 // s2 in 31-bits, because we force signed ints.
19675 // in other case %= will fail.
19676 n = len > 2000 ? 2000 : len;
19677 len -= n;
19678
19679 do {
19680 s1 = s1 + buf[pos++] |0;
19681 s2 = s2 + s1 |0;
19682 } while (--n);
19683
19684 s1 %= 65521;
19685 s2 %= 65521;
19686 }
19687
19688 return s1 | s2 << 16 |0;
19689}
19690
19691// Note: we can't get significant speed boost here.
19692// So write code to minimize size - no pregenerated tables
19693// and array tools dependencies.
19694
19695// (C) 1995-2013 Jean-loup Gailly and Mark Adler
19696// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
19697//
19698// This software is provided 'as-is', without any express or implied
19699// warranty. In no event will the authors be held liable for any damages
19700// arising from the use of this software.
19701//
19702// Permission is granted to anyone to use this software for any purpose,
19703// including commercial applications, and to alter it and redistribute it
19704// freely, subject to the following restrictions:
19705//
19706// 1. The origin of this software must not be misrepresented; you must not
19707// claim that you wrote the original software. If you use this software
19708// in a product, an acknowledgment in the product documentation would be
19709// appreciated but is not required.
19710// 2. Altered source versions must be plainly marked as such, and must not be
19711// misrepresented as being the original software.
19712// 3. This notice may not be removed or altered from any source distribution.
19713
19714// Use ordinary array, since untyped makes no boost here
19715function makeTable() {
19716 let c;
19717 const table = [];
19718
19719 for (let n = 0; n < 256; n++) {
19720 c = n;
19721 for (let k = 0; k < 8; k++) {
19722 c = c & 1 ? 0xEDB88320 ^ c >>> 1 : c >>> 1;
19723 }
19724 table[n] = c;
19725 }
19726
19727 return table;
19728}
19729
19730// Create table on load. Just 255 signed longs. Not a problem.
19731const crcTable = makeTable();
19732
19733
19734function crc32(crc, buf, len, pos) {
19735 const t = crcTable,
19736 end = pos + len;
19737
19738 crc ^= -1;
19739
19740 for (let i = pos; i < end; i++) {
19741 crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 0xFF];
19742 }
19743
19744 return crc ^ -1; // >>> 0;
19745}
19746
19747// (C) 1995-2013 Jean-loup Gailly and Mark Adler
19748// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
19749//
19750// This software is provided 'as-is', without any express or implied
19751// warranty. In no event will the authors be held liable for any damages
19752// arising from the use of this software.
19753//
19754// Permission is granted to anyone to use this software for any purpose,
19755// including commercial applications, and to alter it and redistribute it
19756// freely, subject to the following restrictions:
19757//
19758// 1. The origin of this software must not be misrepresented; you must not
19759// claim that you wrote the original software. If you use this software
19760// in a product, an acknowledgment in the product documentation would be
19761// appreciated but is not required.
19762// 2. Altered source versions must be plainly marked as such, and must not be
19763// misrepresented as being the original software.
19764// 3. This notice may not be removed or altered from any source distribution.
19765
19766var msg = {
19767 2: "need dictionary", /* Z_NEED_DICT 2 */
19768 1: "stream end", /* Z_STREAM_END 1 */
19769 0: "", /* Z_OK 0 */
19770 "-1": "file error", /* Z_ERRNO (-1) */
19771 "-2": "stream error", /* Z_STREAM_ERROR (-2) */
19772 "-3": "data error", /* Z_DATA_ERROR (-3) */
19773 "-4": "insufficient memory", /* Z_MEM_ERROR (-4) */
19774 "-5": "buffer error", /* Z_BUF_ERROR (-5) */
19775 "-6": "incompatible version" /* Z_VERSION_ERROR (-6) */
19776};
19777
19778/*============================================================================*/
19779
19780
19781const MAX_MEM_LEVEL = 9;
19782
19783
19784const LENGTH_CODES$1 = 29;
19785/* number of length codes, not counting the special END_BLOCK code */
19786const LITERALS$1 = 256;
19787/* number of literal bytes 0..255 */
19788const L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1;
19789/* number of Literal or Length codes, including the END_BLOCK code */
19790const D_CODES$1 = 30;
19791/* number of distance codes */
19792const BL_CODES$1 = 19;
19793/* number of codes used to transfer the bit lengths */
19794const HEAP_SIZE$1 = 2 * L_CODES$1 + 1;
19795/* maximum heap size */
19796const MAX_BITS$1 = 15;
19797/* All codes must not exceed MAX_BITS bits */
19798
19799const MIN_MATCH$1 = 3;
19800const MAX_MATCH$1 = 258;
19801const MIN_LOOKAHEAD = (MAX_MATCH$1 + MIN_MATCH$1 + 1);
19802
19803const PRESET_DICT = 0x20;
19804
19805const INIT_STATE = 42;
19806const EXTRA_STATE = 69;
19807const NAME_STATE = 73;
19808const COMMENT_STATE = 91;
19809const HCRC_STATE = 103;
19810const BUSY_STATE = 113;
19811const FINISH_STATE = 666;
19812
19813const BS_NEED_MORE = 1; /* block not completed, need more input or more output */
19814const BS_BLOCK_DONE = 2; /* block flush performed */
19815const BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
19816const BS_FINISH_DONE = 4; /* finish done, accept no more input or output */
19817
19818const OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
19819
19820function err(strm, errorCode) {
19821 strm.msg = msg[errorCode];
19822 return errorCode;
19823}
19824
19825function rank(f) {
19826 return ((f) << 1) - ((f) > 4 ? 9 : 0);
19827}
19828
19829function zero$2(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } }
19830
19831
19832/* =========================================================================
19833 * Flush as much pending output as possible. All deflate() output goes
19834 * through this function so some applications may wish to modify it
19835 * to avoid allocating a large strm->output buffer and copying into it.
19836 * (See also read_buf()).
19837 */
19838function flush_pending(strm) {
19839 const s = strm.state;
19840
19841 //_tr_flush_bits(s);
19842 let len = s.pending;
19843 if (len > strm.avail_out) {
19844 len = strm.avail_out;
19845 }
19846 if (len === 0) { return; }
19847
19848 arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
19849 strm.next_out += len;
19850 s.pending_out += len;
19851 strm.total_out += len;
19852 strm.avail_out -= len;
19853 s.pending -= len;
19854 if (s.pending === 0) {
19855 s.pending_out = 0;
19856 }
19857}
19858
19859
19860function flush_block_only(s, last) {
19861 _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
19862 s.block_start = s.strstart;
19863 flush_pending(s.strm);
19864}
19865
19866
19867function put_byte(s, b) {
19868 s.pending_buf[s.pending++] = b;
19869}
19870
19871
19872/* =========================================================================
19873 * Put a short in the pending buffer. The 16-bit value is put in MSB order.
19874 * IN assertion: the stream state is correct and there is enough room in
19875 * pending_buf.
19876 */
19877function putShortMSB(s, b) {
19878 // put_byte(s, (Byte)(b >> 8));
19879 // put_byte(s, (Byte)(b & 0xff));
19880 s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
19881 s.pending_buf[s.pending++] = b & 0xff;
19882}
19883
19884
19885/* ===========================================================================
19886 * Read a new buffer from the current input stream, update the adler32
19887 * and total number of bytes read. All deflate() input goes through
19888 * this function so some applications may wish to modify it to avoid
19889 * allocating a large strm->input buffer and copying from it.
19890 * (See also flush_pending()).
19891 */
19892function read_buf(strm, buf, start, size) {
19893 let len = strm.avail_in;
19894
19895 if (len > size) { len = size; }
19896 if (len === 0) { return 0; }
19897
19898 strm.avail_in -= len;
19899
19900 // zmemcpy(buf, strm->next_in, len);
19901 arraySet(buf, strm.input, strm.next_in, len, start);
19902 if (strm.state.wrap === 1) {
19903 strm.adler = adler32(strm.adler, buf, len, start);
19904 }
19905
19906 else if (strm.state.wrap === 2) {
19907 strm.adler = crc32(strm.adler, buf, len, start);
19908 }
19909
19910 strm.next_in += len;
19911 strm.total_in += len;
19912
19913 return len;
19914}
19915
19916
19917/* ===========================================================================
19918 * Set match_start to the longest match starting at the given string and
19919 * return its length. Matches shorter or equal to prev_length are discarded,
19920 * in which case the result is equal to prev_length and match_start is
19921 * garbage.
19922 * IN assertions: cur_match is the head of the hash chain for the current
19923 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
19924 * OUT assertion: the match length is not greater than s->lookahead.
19925 */
19926function longest_match(s, cur_match) {
19927 let chain_length = s.max_chain_length; /* max hash chain length */
19928 let scan = s.strstart; /* current string */
19929 let match; /* matched string */
19930 let len; /* length of current match */
19931 let best_len = s.prev_length; /* best match length so far */
19932 let nice_match = s.nice_match; /* stop if match long enough */
19933 const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
19934 s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
19935
19936 const _win = s.window; // shortcut
19937
19938 const wmask = s.w_mask;
19939 const prev = s.prev;
19940
19941 /* Stop when cur_match becomes <= limit. To simplify the code,
19942 * we prevent matches with the string of window index 0.
19943 */
19944
19945 const strend = s.strstart + MAX_MATCH$1;
19946 let scan_end1 = _win[scan + best_len - 1];
19947 let scan_end = _win[scan + best_len];
19948
19949 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
19950 * It is easy to get rid of this optimization if necessary.
19951 */
19952 // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
19953
19954 /* Do not waste too much time if we already have a good match: */
19955 if (s.prev_length >= s.good_match) {
19956 chain_length >>= 2;
19957 }
19958 /* Do not look for matches beyond the end of the input. This is necessary
19959 * to make deflate deterministic.
19960 */
19961 if (nice_match > s.lookahead) { nice_match = s.lookahead; }
19962
19963 // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
19964
19965 do {
19966 // Assert(cur_match < s->strstart, "no future");
19967 match = cur_match;
19968
19969 /* Skip to next match if the match length cannot increase
19970 * or if the match length is less than 2. Note that the checks below
19971 * for insufficient lookahead only occur occasionally for performance
19972 * reasons. Therefore uninitialized memory will be accessed, and
19973 * conditional jumps will be made that depend on those values.
19974 * However the length of the match is limited to the lookahead, so
19975 * the output of deflate is not affected by the uninitialized values.
19976 */
19977
19978 if (_win[match + best_len] !== scan_end ||
19979 _win[match + best_len - 1] !== scan_end1 ||
19980 _win[match] !== _win[scan] ||
19981 _win[++match] !== _win[scan + 1]) {
19982 continue;
19983 }
19984
19985 /* The check at best_len-1 can be removed because it will be made
19986 * again later. (This heuristic is not always a win.)
19987 * It is not necessary to compare scan[2] and match[2] since they
19988 * are always equal when the other bytes match, given that
19989 * the hash keys are equal and that HASH_BITS >= 8.
19990 */
19991 scan += 2;
19992 match++;
19993 // Assert(*scan == *match, "match[2]?");
19994
19995 /* We check for insufficient lookahead only every 8th comparison;
19996 * the 256th check will be made at strstart+258.
19997 */
19998 do {
19999 /*jshint noempty:false*/
20000 } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
20001 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
20002 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
20003 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
20004 scan < strend);
20005
20006 // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
20007
20008 len = MAX_MATCH$1 - (strend - scan);
20009 scan = strend - MAX_MATCH$1;
20010
20011 if (len > best_len) {
20012 s.match_start = cur_match;
20013 best_len = len;
20014 if (len >= nice_match) {
20015 break;
20016 }
20017 scan_end1 = _win[scan + best_len - 1];
20018 scan_end = _win[scan + best_len];
20019 }
20020 } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
20021
20022 if (best_len <= s.lookahead) {
20023 return best_len;
20024 }
20025 return s.lookahead;
20026}
20027
20028
20029/* ===========================================================================
20030 * Fill the window when the lookahead becomes insufficient.
20031 * Updates strstart and lookahead.
20032 *
20033 * IN assertion: lookahead < MIN_LOOKAHEAD
20034 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
20035 * At least one byte has been read, or avail_in == 0; reads are
20036 * performed for at least two bytes (required for the zip translate_eol
20037 * option -- not supported here).
20038 */
20039function fill_window(s) {
20040 const _w_size = s.w_size;
20041 let p, n, m, more, str;
20042
20043 //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
20044
20045 do {
20046 more = s.window_size - s.lookahead - s.strstart;
20047
20048 // JS ints have 32 bit, block below not needed
20049 /* Deal with !@#$% 64K limit: */
20050 //if (sizeof(int) <= 2) {
20051 // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
20052 // more = wsize;
20053 //
20054 // } else if (more == (unsigned)(-1)) {
20055 // /* Very unlikely, but possible on 16 bit machine if
20056 // * strstart == 0 && lookahead == 1 (input done a byte at time)
20057 // */
20058 // more--;
20059 // }
20060 //}
20061
20062
20063 /* If the window is almost full and there is insufficient lookahead,
20064 * move the upper half to the lower one to make room in the upper half.
20065 */
20066 if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
20067
20068 arraySet(s.window, s.window, _w_size, _w_size, 0);
20069 s.match_start -= _w_size;
20070 s.strstart -= _w_size;
20071 /* we now have strstart >= MAX_DIST */
20072 s.block_start -= _w_size;
20073
20074 /* Slide the hash table (could be avoided with 32 bit values
20075 at the expense of memory usage). We slide even when level == 0
20076 to keep the hash table consistent if we switch back to level > 0
20077 later. (Using level 0 permanently is not an optimal usage of
20078 zlib, so we don't care about this pathological case.)
20079 */
20080
20081 n = s.hash_size;
20082 p = n;
20083 do {
20084 m = s.head[--p];
20085 s.head[p] = (m >= _w_size ? m - _w_size : 0);
20086 } while (--n);
20087
20088 n = _w_size;
20089 p = n;
20090 do {
20091 m = s.prev[--p];
20092 s.prev[p] = (m >= _w_size ? m - _w_size : 0);
20093 /* If n is not on any hash chain, prev[n] is garbage but
20094 * its value will never be used.
20095 */
20096 } while (--n);
20097
20098 more += _w_size;
20099 }
20100 if (s.strm.avail_in === 0) {
20101 break;
20102 }
20103
20104 /* If there was no sliding:
20105 * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
20106 * more == window_size - lookahead - strstart
20107 * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
20108 * => more >= window_size - 2*WSIZE + 2
20109 * In the BIG_MEM or MMAP case (not yet supported),
20110 * window_size == input_size + MIN_LOOKAHEAD &&
20111 * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
20112 * Otherwise, window_size == 2*WSIZE so more >= 2.
20113 * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
20114 */
20115 //Assert(more >= 2, "more < 2");
20116 n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
20117 s.lookahead += n;
20118
20119 /* Initialize the hash value now that we have some input: */
20120 if (s.lookahead + s.insert >= MIN_MATCH$1) {
20121 str = s.strstart - s.insert;
20122 s.ins_h = s.window[str];
20123
20124 /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
20125 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
20126 //#if MIN_MATCH != 3
20127 // Call update_hash() MIN_MATCH-3 more times
20128 //#endif
20129 while (s.insert) {
20130 /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
20131 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH$1 - 1]) & s.hash_mask;
20132
20133 s.prev[str & s.w_mask] = s.head[s.ins_h];
20134 s.head[s.ins_h] = str;
20135 str++;
20136 s.insert--;
20137 if (s.lookahead + s.insert < MIN_MATCH$1) {
20138 break;
20139 }
20140 }
20141 }
20142 /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
20143 * but this is not important since only literal bytes will be emitted.
20144 */
20145
20146 } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
20147
20148 /* If the WIN_INIT bytes after the end of the current data have never been
20149 * written, then zero those bytes in order to avoid memory check reports of
20150 * the use of uninitialized (or uninitialised as Julian writes) bytes by
20151 * the longest match routines. Update the high water mark for the next
20152 * time through here. WIN_INIT is set to MAX_MATCH since the longest match
20153 * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
20154 */
20155 // if (s.high_water < s.window_size) {
20156 // var curr = s.strstart + s.lookahead;
20157 // var init = 0;
20158 //
20159 // if (s.high_water < curr) {
20160 // /* Previous high water mark below current data -- zero WIN_INIT
20161 // * bytes or up to end of window, whichever is less.
20162 // */
20163 // init = s.window_size - curr;
20164 // if (init > WIN_INIT)
20165 // init = WIN_INIT;
20166 // zmemzero(s->window + curr, (unsigned)init);
20167 // s->high_water = curr + init;
20168 // }
20169 // else if (s->high_water < (ulg)curr + WIN_INIT) {
20170 // /* High water mark at or above current data, but below current data
20171 // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
20172 // * to end of window, whichever is less.
20173 // */
20174 // init = (ulg)curr + WIN_INIT - s->high_water;
20175 // if (init > s->window_size - s->high_water)
20176 // init = s->window_size - s->high_water;
20177 // zmemzero(s->window + s->high_water, (unsigned)init);
20178 // s->high_water += init;
20179 // }
20180 // }
20181 //
20182 // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
20183 // "not enough room for search");
20184}
20185
20186/* ===========================================================================
20187 * Copy without compression as much as possible from the input stream, return
20188 * the current block state.
20189 * This function does not insert new strings in the dictionary since
20190 * uncompressible data is probably not useful. This function is used
20191 * only for the level=0 compression option.
20192 * NOTE: this function should be optimized to avoid extra copying from
20193 * window to pending_buf.
20194 */
20195function deflate_stored(s, flush) {
20196 /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
20197 * to pending_buf_size, and each stored block has a 5 byte header:
20198 */
20199 let max_block_size = 0xffff;
20200
20201 if (max_block_size > s.pending_buf_size - 5) {
20202 max_block_size = s.pending_buf_size - 5;
20203 }
20204
20205 /* Copy as much as possible from input to output: */
20206 for (; ;) {
20207 /* Fill the window as much as possible: */
20208 if (s.lookahead <= 1) {
20209
20210 //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
20211 // s->block_start >= (long)s->w_size, "slide too late");
20212 // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
20213 // s.block_start >= s.w_size)) {
20214 // throw new Error("slide too late");
20215 // }
20216
20217 fill_window(s);
20218 if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
20219 return BS_NEED_MORE;
20220 }
20221
20222 if (s.lookahead === 0) {
20223 break;
20224 }
20225 /* flush the current block */
20226 }
20227 //Assert(s->block_start >= 0L, "block gone");
20228 // if (s.block_start < 0) throw new Error("block gone");
20229
20230 s.strstart += s.lookahead;
20231 s.lookahead = 0;
20232
20233 /* Emit a stored block if pending_buf will be full: */
20234 const max_start = s.block_start + max_block_size;
20235
20236 if (s.strstart === 0 || s.strstart >= max_start) {
20237 /* strstart == 0 is possible when wraparound on 16-bit machine */
20238 s.lookahead = s.strstart - max_start;
20239 s.strstart = max_start;
20240 /*** FLUSH_BLOCK(s, 0); ***/
20241 flush_block_only(s, false);
20242 if (s.strm.avail_out === 0) {
20243 return BS_NEED_MORE;
20244 }
20245 /***/
20246
20247
20248 }
20249 /* Flush if we may have to slide, otherwise block_start may become
20250 * negative and the data will be gone:
20251 */
20252 if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
20253 /*** FLUSH_BLOCK(s, 0); ***/
20254 flush_block_only(s, false);
20255 if (s.strm.avail_out === 0) {
20256 return BS_NEED_MORE;
20257 }
20258 /***/
20259 }
20260 }
20261
20262 s.insert = 0;
20263
20264 if (flush === Z_FINISH) {
20265 /*** FLUSH_BLOCK(s, 1); ***/
20266 flush_block_only(s, true);
20267 if (s.strm.avail_out === 0) {
20268 return BS_FINISH_STARTED;
20269 }
20270 /***/
20271 return BS_FINISH_DONE;
20272 }
20273
20274 if (s.strstart > s.block_start) {
20275 /*** FLUSH_BLOCK(s, 0); ***/
20276 flush_block_only(s, false);
20277 if (s.strm.avail_out === 0) {
20278 return BS_NEED_MORE;
20279 }
20280 /***/
20281 }
20282
20283 return BS_NEED_MORE;
20284}
20285
20286/* ===========================================================================
20287 * Compress as much as possible from the input stream, return the current
20288 * block state.
20289 * This function does not perform lazy evaluation of matches and inserts
20290 * new strings in the dictionary only for unmatched strings or for short
20291 * matches. It is used only for the fast compression options.
20292 */
20293function deflate_fast(s, flush) {
20294 let hash_head; /* head of the hash chain */
20295 let bflush; /* set if current block must be flushed */
20296
20297 for (; ;) {
20298 /* Make sure that we always have enough lookahead, except
20299 * at the end of the input file. We need MAX_MATCH bytes
20300 * for the next match, plus MIN_MATCH bytes to insert the
20301 * string following the next match.
20302 */
20303 if (s.lookahead < MIN_LOOKAHEAD) {
20304 fill_window(s);
20305 if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
20306 return BS_NEED_MORE;
20307 }
20308 if (s.lookahead === 0) {
20309 break; /* flush the current block */
20310 }
20311 }
20312
20313 /* Insert the string window[strstart .. strstart+2] in the
20314 * dictionary, and set hash_head to the head of the hash chain:
20315 */
20316 hash_head = 0/*NIL*/;
20317 if (s.lookahead >= MIN_MATCH$1) {
20318 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
20319 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
20320 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
20321 s.head[s.ins_h] = s.strstart;
20322 /***/
20323 }
20324
20325 /* Find the longest match, discarding those <= prev_length.
20326 * At this point we have always match_length < MIN_MATCH
20327 */
20328 if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
20329 /* To simplify the code, we prevent matches with the string
20330 * of window index 0 (in particular we have to avoid a match
20331 * of the string with itself at the start of the input file).
20332 */
20333 s.match_length = longest_match(s, hash_head);
20334 /* longest_match() sets match_start */
20335 }
20336 if (s.match_length >= MIN_MATCH$1) {
20337 // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
20338
20339 /*** _tr_tally_dist(s, s.strstart - s.match_start,
20340 s.match_length - MIN_MATCH, bflush); ***/
20341 bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH$1);
20342
20343 s.lookahead -= s.match_length;
20344
20345 /* Insert new strings in the hash table only if the match length
20346 * is not too large. This saves time but degrades compression.
20347 */
20348 if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH$1) {
20349 s.match_length--; /* string at strstart already in table */
20350 do {
20351 s.strstart++;
20352 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
20353 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
20354 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
20355 s.head[s.ins_h] = s.strstart;
20356 /***/
20357 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
20358 * always MIN_MATCH bytes ahead.
20359 */
20360 } while (--s.match_length !== 0);
20361 s.strstart++;
20362 } else {
20363 s.strstart += s.match_length;
20364 s.match_length = 0;
20365 s.ins_h = s.window[s.strstart];
20366 /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
20367 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
20368
20369 //#if MIN_MATCH != 3
20370 // Call UPDATE_HASH() MIN_MATCH-3 more times
20371 //#endif
20372 /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
20373 * matter since it will be recomputed at next deflate call.
20374 */
20375 }
20376 } else {
20377 /* No match, output a literal byte */
20378 //Tracevv((stderr,"%c", s.window[s.strstart]));
20379 /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
20380 bflush = _tr_tally(s, 0, s.window[s.strstart]);
20381
20382 s.lookahead--;
20383 s.strstart++;
20384 }
20385 if (bflush) {
20386 /*** FLUSH_BLOCK(s, 0); ***/
20387 flush_block_only(s, false);
20388 if (s.strm.avail_out === 0) {
20389 return BS_NEED_MORE;
20390 }
20391 /***/
20392 }
20393 }
20394 s.insert = ((s.strstart < (MIN_MATCH$1 - 1)) ? s.strstart : MIN_MATCH$1 - 1);
20395 if (flush === Z_FINISH) {
20396 /*** FLUSH_BLOCK(s, 1); ***/
20397 flush_block_only(s, true);
20398 if (s.strm.avail_out === 0) {
20399 return BS_FINISH_STARTED;
20400 }
20401 /***/
20402 return BS_FINISH_DONE;
20403 }
20404 if (s.last_lit) {
20405 /*** FLUSH_BLOCK(s, 0); ***/
20406 flush_block_only(s, false);
20407 if (s.strm.avail_out === 0) {
20408 return BS_NEED_MORE;
20409 }
20410 /***/
20411 }
20412 return BS_BLOCK_DONE;
20413}
20414
20415/* ===========================================================================
20416 * Same as above, but achieves better compression. We use a lazy
20417 * evaluation for matches: a match is finally adopted only if there is
20418 * no better match at the next window position.
20419 */
20420function deflate_slow(s, flush) {
20421 let hash_head; /* head of hash chain */
20422 let bflush; /* set if current block must be flushed */
20423
20424 let max_insert;
20425
20426 /* Process the input block. */
20427 for (; ;) {
20428 /* Make sure that we always have enough lookahead, except
20429 * at the end of the input file. We need MAX_MATCH bytes
20430 * for the next match, plus MIN_MATCH bytes to insert the
20431 * string following the next match.
20432 */
20433 if (s.lookahead < MIN_LOOKAHEAD) {
20434 fill_window(s);
20435 if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
20436 return BS_NEED_MORE;
20437 }
20438 if (s.lookahead === 0) { break; } /* flush the current block */
20439 }
20440
20441 /* Insert the string window[strstart .. strstart+2] in the
20442 * dictionary, and set hash_head to the head of the hash chain:
20443 */
20444 hash_head = 0/*NIL*/;
20445 if (s.lookahead >= MIN_MATCH$1) {
20446 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
20447 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
20448 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
20449 s.head[s.ins_h] = s.strstart;
20450 /***/
20451 }
20452
20453 /* Find the longest match, discarding those <= prev_length.
20454 */
20455 s.prev_length = s.match_length;
20456 s.prev_match = s.match_start;
20457 s.match_length = MIN_MATCH$1 - 1;
20458
20459 if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
20460 s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
20461 /* To simplify the code, we prevent matches with the string
20462 * of window index 0 (in particular we have to avoid a match
20463 * of the string with itself at the start of the input file).
20464 */
20465 s.match_length = longest_match(s, hash_head);
20466 /* longest_match() sets match_start */
20467
20468 if (s.match_length <= 5 &&
20469 (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH$1 && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
20470
20471 /* If prev_match is also MIN_MATCH, match_start is garbage
20472 * but we will ignore the current match anyway.
20473 */
20474 s.match_length = MIN_MATCH$1 - 1;
20475 }
20476 }
20477 /* If there was a match at the previous step and the current
20478 * match is not better, output the previous match:
20479 */
20480 if (s.prev_length >= MIN_MATCH$1 && s.match_length <= s.prev_length) {
20481 max_insert = s.strstart + s.lookahead - MIN_MATCH$1;
20482 /* Do not insert strings in hash table beyond this. */
20483
20484 //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
20485
20486 /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
20487 s.prev_length - MIN_MATCH, bflush);***/
20488 bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH$1);
20489 /* Insert in hash table all strings up to the end of the match.
20490 * strstart-1 and strstart are already inserted. If there is not
20491 * enough lookahead, the last two strings are not inserted in
20492 * the hash table.
20493 */
20494 s.lookahead -= s.prev_length - 1;
20495 s.prev_length -= 2;
20496 do {
20497 if (++s.strstart <= max_insert) {
20498 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
20499 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
20500 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
20501 s.head[s.ins_h] = s.strstart;
20502 /***/
20503 }
20504 } while (--s.prev_length !== 0);
20505 s.match_available = 0;
20506 s.match_length = MIN_MATCH$1 - 1;
20507 s.strstart++;
20508
20509 if (bflush) {
20510 /*** FLUSH_BLOCK(s, 0); ***/
20511 flush_block_only(s, false);
20512 if (s.strm.avail_out === 0) {
20513 return BS_NEED_MORE;
20514 }
20515 /***/
20516 }
20517
20518 } else if (s.match_available) {
20519 /* If there was no match at the previous position, output a
20520 * single literal. If there was a match but the current match
20521 * is longer, truncate the previous match to a single literal.
20522 */
20523 //Tracevv((stderr,"%c", s->window[s->strstart-1]));
20524 /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
20525 bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);
20526
20527 if (bflush) {
20528 /*** FLUSH_BLOCK_ONLY(s, 0) ***/
20529 flush_block_only(s, false);
20530 /***/
20531 }
20532 s.strstart++;
20533 s.lookahead--;
20534 if (s.strm.avail_out === 0) {
20535 return BS_NEED_MORE;
20536 }
20537 } else {
20538 /* There is no previous match to compare with, wait for
20539 * the next step to decide.
20540 */
20541 s.match_available = 1;
20542 s.strstart++;
20543 s.lookahead--;
20544 }
20545 }
20546 //Assert (flush != Z_NO_FLUSH, "no flush?");
20547 if (s.match_available) {
20548 //Tracevv((stderr,"%c", s->window[s->strstart-1]));
20549 /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
20550 bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);
20551
20552 s.match_available = 0;
20553 }
20554 s.insert = s.strstart < MIN_MATCH$1 - 1 ? s.strstart : MIN_MATCH$1 - 1;
20555 if (flush === Z_FINISH) {
20556 /*** FLUSH_BLOCK(s, 1); ***/
20557 flush_block_only(s, true);
20558 if (s.strm.avail_out === 0) {
20559 return BS_FINISH_STARTED;
20560 }
20561 /***/
20562 return BS_FINISH_DONE;
20563 }
20564 if (s.last_lit) {
20565 /*** FLUSH_BLOCK(s, 0); ***/
20566 flush_block_only(s, false);
20567 if (s.strm.avail_out === 0) {
20568 return BS_NEED_MORE;
20569 }
20570 /***/
20571 }
20572
20573 return BS_BLOCK_DONE;
20574}
20575
20576
20577/* ===========================================================================
20578 * For Z_RLE, simply look for runs of bytes, generate matches only of distance
20579 * one. Do not maintain a hash table. (It will be regenerated if this run of
20580 * deflate switches away from Z_RLE.)
20581 */
20582function deflate_rle(s, flush) {
20583 let bflush; /* set if current block must be flushed */
20584 let prev; /* byte at distance one to match */
20585 let scan, strend; /* scan goes up to strend for length of run */
20586
20587 const _win = s.window;
20588
20589 for (; ;) {
20590 /* Make sure that we always have enough lookahead, except
20591 * at the end of the input file. We need MAX_MATCH bytes
20592 * for the longest run, plus one for the unrolled loop.
20593 */
20594 if (s.lookahead <= MAX_MATCH$1) {
20595 fill_window(s);
20596 if (s.lookahead <= MAX_MATCH$1 && flush === Z_NO_FLUSH) {
20597 return BS_NEED_MORE;
20598 }
20599 if (s.lookahead === 0) { break; } /* flush the current block */
20600 }
20601
20602 /* See how many times the previous byte repeats */
20603 s.match_length = 0;
20604 if (s.lookahead >= MIN_MATCH$1 && s.strstart > 0) {
20605 scan = s.strstart - 1;
20606 prev = _win[scan];
20607 if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
20608 strend = s.strstart + MAX_MATCH$1;
20609 do {
20610 /*jshint noempty:false*/
20611 } while (prev === _win[++scan] && prev === _win[++scan] &&
20612 prev === _win[++scan] && prev === _win[++scan] &&
20613 prev === _win[++scan] && prev === _win[++scan] &&
20614 prev === _win[++scan] && prev === _win[++scan] &&
20615 scan < strend);
20616 s.match_length = MAX_MATCH$1 - (strend - scan);
20617 if (s.match_length > s.lookahead) {
20618 s.match_length = s.lookahead;
20619 }
20620 }
20621 //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
20622 }
20623
20624 /* Emit match if have run of MIN_MATCH or longer, else emit literal */
20625 if (s.match_length >= MIN_MATCH$1) {
20626 //check_match(s, s.strstart, s.strstart - 1, s.match_length);
20627
20628 /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
20629 bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH$1);
20630
20631 s.lookahead -= s.match_length;
20632 s.strstart += s.match_length;
20633 s.match_length = 0;
20634 } else {
20635 /* No match, output a literal byte */
20636 //Tracevv((stderr,"%c", s->window[s->strstart]));
20637 /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
20638 bflush = _tr_tally(s, 0, s.window[s.strstart]);
20639
20640 s.lookahead--;
20641 s.strstart++;
20642 }
20643 if (bflush) {
20644 /*** FLUSH_BLOCK(s, 0); ***/
20645 flush_block_only(s, false);
20646 if (s.strm.avail_out === 0) {
20647 return BS_NEED_MORE;
20648 }
20649 /***/
20650 }
20651 }
20652 s.insert = 0;
20653 if (flush === Z_FINISH) {
20654 /*** FLUSH_BLOCK(s, 1); ***/
20655 flush_block_only(s, true);
20656 if (s.strm.avail_out === 0) {
20657 return BS_FINISH_STARTED;
20658 }
20659 /***/
20660 return BS_FINISH_DONE;
20661 }
20662 if (s.last_lit) {
20663 /*** FLUSH_BLOCK(s, 0); ***/
20664 flush_block_only(s, false);
20665 if (s.strm.avail_out === 0) {
20666 return BS_NEED_MORE;
20667 }
20668 /***/
20669 }
20670 return BS_BLOCK_DONE;
20671}
20672
20673/* ===========================================================================
20674 * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
20675 * (It will be regenerated if this run of deflate switches away from Huffman.)
20676 */
20677function deflate_huff(s, flush) {
20678 let bflush; /* set if current block must be flushed */
20679
20680 for (; ;) {
20681 /* Make sure that we have a literal to write. */
20682 if (s.lookahead === 0) {
20683 fill_window(s);
20684 if (s.lookahead === 0) {
20685 if (flush === Z_NO_FLUSH) {
20686 return BS_NEED_MORE;
20687 }
20688 break; /* flush the current block */
20689 }
20690 }
20691
20692 /* Output a literal byte */
20693 s.match_length = 0;
20694 //Tracevv((stderr,"%c", s->window[s->strstart]));
20695 /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
20696 bflush = _tr_tally(s, 0, s.window[s.strstart]);
20697 s.lookahead--;
20698 s.strstart++;
20699 if (bflush) {
20700 /*** FLUSH_BLOCK(s, 0); ***/
20701 flush_block_only(s, false);
20702 if (s.strm.avail_out === 0) {
20703 return BS_NEED_MORE;
20704 }
20705 /***/
20706 }
20707 }
20708 s.insert = 0;
20709 if (flush === Z_FINISH) {
20710 /*** FLUSH_BLOCK(s, 1); ***/
20711 flush_block_only(s, true);
20712 if (s.strm.avail_out === 0) {
20713 return BS_FINISH_STARTED;
20714 }
20715 /***/
20716 return BS_FINISH_DONE;
20717 }
20718 if (s.last_lit) {
20719 /*** FLUSH_BLOCK(s, 0); ***/
20720 flush_block_only(s, false);
20721 if (s.strm.avail_out === 0) {
20722 return BS_NEED_MORE;
20723 }
20724 /***/
20725 }
20726 return BS_BLOCK_DONE;
20727}
20728
20729/* Values for max_lazy_match, good_match and max_chain_length, depending on
20730 * the desired pack level (0..9). The values given below have been tuned to
20731 * exclude worst case performance for pathological files. Better values may be
20732 * found for specific files.
20733 */
20734class Config {
20735 constructor(good_length, max_lazy, nice_length, max_chain, func) {
20736 this.good_length = good_length;
20737 this.max_lazy = max_lazy;
20738 this.nice_length = nice_length;
20739 this.max_chain = max_chain;
20740 this.func = func;
20741 }
20742}
20743const configuration_table = [
20744 /* good lazy nice chain */
20745 new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */
20746 new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */
20747 new Config(4, 5, 16, 8, deflate_fast), /* 2 */
20748 new Config(4, 6, 32, 32, deflate_fast), /* 3 */
20749
20750 new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */
20751 new Config(8, 16, 32, 32, deflate_slow), /* 5 */
20752 new Config(8, 16, 128, 128, deflate_slow), /* 6 */
20753 new Config(8, 32, 128, 256, deflate_slow), /* 7 */
20754 new Config(32, 128, 258, 1024, deflate_slow), /* 8 */
20755 new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */
20756];
20757
20758
20759/* ===========================================================================
20760 * Initialize the "longest match" routines for a new zlib stream
20761 */
20762function lm_init(s) {
20763 s.window_size = 2 * s.w_size;
20764
20765 /*** CLEAR_HASH(s); ***/
20766 zero$2(s.head); // Fill with NIL (= 0);
20767
20768 /* Set the default configuration parameters:
20769 */
20770 s.max_lazy_match = configuration_table[s.level].max_lazy;
20771 s.good_match = configuration_table[s.level].good_length;
20772 s.nice_match = configuration_table[s.level].nice_length;
20773 s.max_chain_length = configuration_table[s.level].max_chain;
20774
20775 s.strstart = 0;
20776 s.block_start = 0;
20777 s.lookahead = 0;
20778 s.insert = 0;
20779 s.match_length = s.prev_length = MIN_MATCH$1 - 1;
20780 s.match_available = 0;
20781 s.ins_h = 0;
20782}
20783
20784class DeflateState {
20785 constructor() {
20786 this.strm = null; /* pointer back to this zlib stream */
20787 this.status = 0; /* as the name implies */
20788 this.pending_buf = null; /* output still pending */
20789 this.pending_buf_size = 0; /* size of pending_buf */
20790 this.pending_out = 0; /* next pending byte to output to the stream */
20791 this.pending = 0; /* nb of bytes in the pending buffer */
20792 this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
20793 this.gzhead = null; /* gzip header information to write */
20794 this.gzindex = 0; /* where in extra, name, or comment */
20795 this.method = Z_DEFLATED; /* can only be DEFLATED */
20796 this.last_flush = -1; /* value of flush param for previous deflate call */
20797
20798 this.w_size = 0; /* LZ77 window size (32K by default) */
20799 this.w_bits = 0; /* log2(w_size) (8..16) */
20800 this.w_mask = 0; /* w_size - 1 */
20801
20802 this.window = null;
20803 /* Sliding window. Input bytes are read into the second half of the window,
20804 * and move to the first half later to keep a dictionary of at least wSize
20805 * bytes. With this organization, matches are limited to a distance of
20806 * wSize-MAX_MATCH bytes, but this ensures that IO is always
20807 * performed with a length multiple of the block size.
20808 */
20809
20810 this.window_size = 0;
20811 /* Actual size of window: 2*wSize, except when the user input buffer
20812 * is directly used as sliding window.
20813 */
20814
20815 this.prev = null;
20816 /* Link to older string with same hash index. To limit the size of this
20817 * array to 64K, this link is maintained only for the last 32K strings.
20818 * An index in this array is thus a window index modulo 32K.
20819 */
20820
20821 this.head = null; /* Heads of the hash chains or NIL. */
20822
20823 this.ins_h = 0; /* hash index of string to be inserted */
20824 this.hash_size = 0; /* number of elements in hash table */
20825 this.hash_bits = 0; /* log2(hash_size) */
20826 this.hash_mask = 0; /* hash_size-1 */
20827
20828 this.hash_shift = 0;
20829 /* Number of bits by which ins_h must be shifted at each input
20830 * step. It must be such that after MIN_MATCH steps, the oldest
20831 * byte no longer takes part in the hash key, that is:
20832 * hash_shift * MIN_MATCH >= hash_bits
20833 */
20834
20835 this.block_start = 0;
20836 /* Window position at the beginning of the current output block. Gets
20837 * negative when the window is moved backwards.
20838 */
20839
20840 this.match_length = 0; /* length of best match */
20841 this.prev_match = 0; /* previous match */
20842 this.match_available = 0; /* set if previous match exists */
20843 this.strstart = 0; /* start of string to insert */
20844 this.match_start = 0; /* start of matching string */
20845 this.lookahead = 0; /* number of valid bytes ahead in window */
20846
20847 this.prev_length = 0;
20848 /* Length of the best match at previous step. Matches not greater than this
20849 * are discarded. This is used in the lazy match evaluation.
20850 */
20851
20852 this.max_chain_length = 0;
20853 /* To speed up deflation, hash chains are never searched beyond this
20854 * length. A higher limit improves compression ratio but degrades the
20855 * speed.
20856 */
20857
20858 this.max_lazy_match = 0;
20859 /* Attempt to find a better match only when the current match is strictly
20860 * smaller than this value. This mechanism is used only for compression
20861 * levels >= 4.
20862 */
20863 // That's alias to max_lazy_match, don't use directly
20864 //this.max_insert_length = 0;
20865 /* Insert new strings in the hash table only if the match length is not
20866 * greater than this length. This saves time but degrades compression.
20867 * max_insert_length is used only for compression levels <= 3.
20868 */
20869
20870 this.level = 0; /* compression level (1..9) */
20871 this.strategy = 0; /* favor or force Huffman coding*/
20872
20873 this.good_match = 0;
20874 /* Use a faster search when the previous match is longer than this */
20875
20876 this.nice_match = 0; /* Stop searching when current match exceeds this */
20877
20878 /* used by trees.c: */
20879
20880 /* Didn't use ct_data typedef below to suppress compiler warning */
20881
20882 // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
20883 // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
20884 // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
20885
20886 // Use flat array of DOUBLE size, with interleaved fata,
20887 // because JS does not support effective
20888 this.dyn_ltree = new Buf16(HEAP_SIZE$1 * 2);
20889 this.dyn_dtree = new Buf16((2 * D_CODES$1 + 1) * 2);
20890 this.bl_tree = new Buf16((2 * BL_CODES$1 + 1) * 2);
20891 zero$2(this.dyn_ltree);
20892 zero$2(this.dyn_dtree);
20893 zero$2(this.bl_tree);
20894
20895 this.l_desc = null; /* desc. for literal tree */
20896 this.d_desc = null; /* desc. for distance tree */
20897 this.bl_desc = null; /* desc. for bit length tree */
20898
20899 //ush bl_count[MAX_BITS+1];
20900 this.bl_count = new Buf16(MAX_BITS$1 + 1);
20901 /* number of codes at each bit length for an optimal tree */
20902
20903 //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
20904 this.heap = new Buf16(2 * L_CODES$1 + 1); /* heap used to build the Huffman trees */
20905 zero$2(this.heap);
20906
20907 this.heap_len = 0; /* number of elements in the heap */
20908 this.heap_max = 0; /* element of largest frequency */
20909 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
20910 * The same heap array is used to build all trees.
20911 */
20912
20913 this.depth = new Buf16(2 * L_CODES$1 + 1); //uch depth[2*L_CODES+1];
20914 zero$2(this.depth);
20915 /* Depth of each subtree used as tie breaker for trees of equal frequency
20916 */
20917
20918 this.l_buf = 0; /* buffer index for literals or lengths */
20919
20920 this.lit_bufsize = 0;
20921 /* Size of match buffer for literals/lengths. There are 4 reasons for
20922 * limiting lit_bufsize to 64K:
20923 * - frequencies can be kept in 16 bit counters
20924 * - if compression is not successful for the first block, all input
20925 * data is still in the window so we can still emit a stored block even
20926 * when input comes from standard input. (This can also be done for
20927 * all blocks if lit_bufsize is not greater than 32K.)
20928 * - if compression is not successful for a file smaller than 64K, we can
20929 * even emit a stored file instead of a stored block (saving 5 bytes).
20930 * This is applicable only for zip (not gzip or zlib).
20931 * - creating new Huffman trees less frequently may not provide fast
20932 * adaptation to changes in the input data statistics. (Take for
20933 * example a binary file with poorly compressible code followed by
20934 * a highly compressible string table.) Smaller buffer sizes give
20935 * fast adaptation but have of course the overhead of transmitting
20936 * trees more frequently.
20937 * - I can't count above 4
20938 */
20939
20940 this.last_lit = 0; /* running index in l_buf */
20941
20942 this.d_buf = 0;
20943 /* Buffer index for distances. To simplify the code, d_buf and l_buf have
20944 * the same number of elements. To use different lengths, an extra flag
20945 * array would be necessary.
20946 */
20947
20948 this.opt_len = 0; /* bit length of current block with optimal trees */
20949 this.static_len = 0; /* bit length of current block with static trees */
20950 this.matches = 0; /* number of string matches in current block */
20951 this.insert = 0; /* bytes at end of window left to insert */
20952
20953
20954 this.bi_buf = 0;
20955 /* Output buffer. bits are inserted starting at the bottom (least
20956 * significant bits).
20957 */
20958 this.bi_valid = 0;
20959 /* Number of valid bits in bi_buf. All bits above the last valid bit
20960 * are always zero.
20961 */
20962
20963 // Used for window memory init. We safely ignore it for JS. That makes
20964 // sense only for pointers and memory check tools.
20965 //this.high_water = 0;
20966 /* High water mark offset in window for initialized bytes -- bytes above
20967 * this are set to zero in order to avoid memory check warnings when
20968 * longest match routines access bytes past the input. This is then
20969 * updated to the new high water mark.
20970 */
20971 }
20972}
20973
20974function deflateResetKeep(strm) {
20975 let s;
20976
20977 if (!strm || !strm.state) {
20978 return err(strm, Z_STREAM_ERROR);
20979 }
20980
20981 strm.total_in = strm.total_out = 0;
20982 strm.data_type = Z_UNKNOWN;
20983
20984 s = strm.state;
20985 s.pending = 0;
20986 s.pending_out = 0;
20987
20988 if (s.wrap < 0) {
20989 s.wrap = -s.wrap;
20990 /* was made negative by deflate(..., Z_FINISH); */
20991 }
20992 s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
20993 strm.adler = (s.wrap === 2) ?
20994 0 // crc32(0, Z_NULL, 0)
20995 :
20996 1; // adler32(0, Z_NULL, 0)
20997 s.last_flush = Z_NO_FLUSH;
20998 _tr_init(s);
20999 return Z_OK;
21000}
21001
21002
21003function deflateReset(strm) {
21004 const ret = deflateResetKeep(strm);
21005 if (ret === Z_OK) {
21006 lm_init(strm.state);
21007 }
21008 return ret;
21009}
21010
21011
21012function deflateSetHeader(strm, head) {
21013 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
21014 if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
21015 strm.state.gzhead = head;
21016 return Z_OK;
21017}
21018
21019
21020function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
21021 if (!strm) { // === Z_NULL
21022 return Z_STREAM_ERROR;
21023 }
21024 let wrap = 1;
21025
21026 if (level === Z_DEFAULT_COMPRESSION) {
21027 level = 6;
21028 }
21029
21030 if (windowBits < 0) { /* suppress zlib wrapper */
21031 wrap = 0;
21032 windowBits = -windowBits;
21033 }
21034
21035 else if (windowBits > 15) {
21036 wrap = 2; /* write gzip wrapper instead */
21037 windowBits -= 16;
21038 }
21039
21040
21041 if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
21042 windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
21043 strategy < 0 || strategy > Z_FIXED) {
21044 return err(strm, Z_STREAM_ERROR);
21045 }
21046
21047
21048 if (windowBits === 8) {
21049 windowBits = 9;
21050 }
21051 /* until 256-byte window bug fixed */
21052
21053 const s = new DeflateState();
21054
21055 strm.state = s;
21056 s.strm = strm;
21057
21058 s.wrap = wrap;
21059 s.gzhead = null;
21060 s.w_bits = windowBits;
21061 s.w_size = 1 << s.w_bits;
21062 s.w_mask = s.w_size - 1;
21063
21064 s.hash_bits = memLevel + 7;
21065 s.hash_size = 1 << s.hash_bits;
21066 s.hash_mask = s.hash_size - 1;
21067 s.hash_shift = ~~((s.hash_bits + MIN_MATCH$1 - 1) / MIN_MATCH$1);
21068 s.window = new Buf8(s.w_size * 2);
21069 s.head = new Buf16(s.hash_size);
21070 s.prev = new Buf16(s.w_size);
21071
21072 // Don't need mem init magic for JS.
21073 //s.high_water = 0; /* nothing written to s->window yet */
21074
21075 s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
21076
21077 s.pending_buf_size = s.lit_bufsize * 4;
21078
21079 //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
21080 //s->pending_buf = (uchf *) overlay;
21081 s.pending_buf = new Buf8(s.pending_buf_size);
21082
21083 // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
21084 //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
21085 s.d_buf = 1 * s.lit_bufsize;
21086
21087 //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
21088 s.l_buf = (1 + 2) * s.lit_bufsize;
21089
21090 s.level = level;
21091 s.strategy = strategy;
21092 s.method = method;
21093
21094 return deflateReset(strm);
21095}
21096
21097
21098function deflate(strm, flush) {
21099 let old_flush, s;
21100 let beg, val; // for gzip header write only
21101
21102 if (!strm || !strm.state ||
21103 flush > Z_BLOCK || flush < 0) {
21104 return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
21105 }
21106
21107 s = strm.state;
21108
21109 if (!strm.output ||
21110 (!strm.input && strm.avail_in !== 0) ||
21111 (s.status === FINISH_STATE && flush !== Z_FINISH)) {
21112 return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
21113 }
21114
21115 s.strm = strm; /* just in case */
21116 old_flush = s.last_flush;
21117 s.last_flush = flush;
21118
21119 /* Write the header */
21120 if (s.status === INIT_STATE) {
21121
21122 if (s.wrap === 2) { // GZIP header
21123 strm.adler = 0; //crc32(0L, Z_NULL, 0);
21124 put_byte(s, 31);
21125 put_byte(s, 139);
21126 put_byte(s, 8);
21127 if (!s.gzhead) { // s->gzhead == Z_NULL
21128 put_byte(s, 0);
21129 put_byte(s, 0);
21130 put_byte(s, 0);
21131 put_byte(s, 0);
21132 put_byte(s, 0);
21133 put_byte(s, s.level === 9 ? 2 :
21134 (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
21135 4 : 0));
21136 put_byte(s, OS_CODE);
21137 s.status = BUSY_STATE;
21138 }
21139 else {
21140 put_byte(s, (s.gzhead.text ? 1 : 0) +
21141 (s.gzhead.hcrc ? 2 : 0) +
21142 (!s.gzhead.extra ? 0 : 4) +
21143 (!s.gzhead.name ? 0 : 8) +
21144 (!s.gzhead.comment ? 0 : 16)
21145 );
21146 put_byte(s, s.gzhead.time & 0xff);
21147 put_byte(s, (s.gzhead.time >> 8) & 0xff);
21148 put_byte(s, (s.gzhead.time >> 16) & 0xff);
21149 put_byte(s, (s.gzhead.time >> 24) & 0xff);
21150 put_byte(s, s.level === 9 ? 2 :
21151 (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
21152 4 : 0));
21153 put_byte(s, s.gzhead.os & 0xff);
21154 if (s.gzhead.extra && s.gzhead.extra.length) {
21155 put_byte(s, s.gzhead.extra.length & 0xff);
21156 put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
21157 }
21158 if (s.gzhead.hcrc) {
21159 strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
21160 }
21161 s.gzindex = 0;
21162 s.status = EXTRA_STATE;
21163 }
21164 }
21165 else // DEFLATE header
21166 {
21167 let header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
21168 let level_flags = -1;
21169
21170 if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
21171 level_flags = 0;
21172 } else if (s.level < 6) {
21173 level_flags = 1;
21174 } else if (s.level === 6) {
21175 level_flags = 2;
21176 } else {
21177 level_flags = 3;
21178 }
21179 header |= (level_flags << 6);
21180 if (s.strstart !== 0) { header |= PRESET_DICT; }
21181 header += 31 - (header % 31);
21182
21183 s.status = BUSY_STATE;
21184 putShortMSB(s, header);
21185
21186 /* Save the adler32 of the preset dictionary: */
21187 if (s.strstart !== 0) {
21188 putShortMSB(s, strm.adler >>> 16);
21189 putShortMSB(s, strm.adler & 0xffff);
21190 }
21191 strm.adler = 1; // adler32(0L, Z_NULL, 0);
21192 }
21193 }
21194
21195 //#ifdef GZIP
21196 if (s.status === EXTRA_STATE) {
21197 if (s.gzhead.extra/* != Z_NULL*/) {
21198 beg = s.pending; /* start of bytes to update crc */
21199
21200 while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
21201 if (s.pending === s.pending_buf_size) {
21202 if (s.gzhead.hcrc && s.pending > beg) {
21203 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
21204 }
21205 flush_pending(strm);
21206 beg = s.pending;
21207 if (s.pending === s.pending_buf_size) {
21208 break;
21209 }
21210 }
21211 put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
21212 s.gzindex++;
21213 }
21214 if (s.gzhead.hcrc && s.pending > beg) {
21215 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
21216 }
21217 if (s.gzindex === s.gzhead.extra.length) {
21218 s.gzindex = 0;
21219 s.status = NAME_STATE;
21220 }
21221 }
21222 else {
21223 s.status = NAME_STATE;
21224 }
21225 }
21226 if (s.status === NAME_STATE) {
21227 if (s.gzhead.name/* != Z_NULL*/) {
21228 beg = s.pending; /* start of bytes to update crc */
21229 //int val;
21230
21231 do {
21232 if (s.pending === s.pending_buf_size) {
21233 if (s.gzhead.hcrc && s.pending > beg) {
21234 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
21235 }
21236 flush_pending(strm);
21237 beg = s.pending;
21238 if (s.pending === s.pending_buf_size) {
21239 val = 1;
21240 break;
21241 }
21242 }
21243 // JS specific: little magic to add zero terminator to end of string
21244 if (s.gzindex < s.gzhead.name.length) {
21245 val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
21246 } else {
21247 val = 0;
21248 }
21249 put_byte(s, val);
21250 } while (val !== 0);
21251
21252 if (s.gzhead.hcrc && s.pending > beg) {
21253 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
21254 }
21255 if (val === 0) {
21256 s.gzindex = 0;
21257 s.status = COMMENT_STATE;
21258 }
21259 }
21260 else {
21261 s.status = COMMENT_STATE;
21262 }
21263 }
21264 if (s.status === COMMENT_STATE) {
21265 if (s.gzhead.comment/* != Z_NULL*/) {
21266 beg = s.pending; /* start of bytes to update crc */
21267 //int val;
21268
21269 do {
21270 if (s.pending === s.pending_buf_size) {
21271 if (s.gzhead.hcrc && s.pending > beg) {
21272 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
21273 }
21274 flush_pending(strm);
21275 beg = s.pending;
21276 if (s.pending === s.pending_buf_size) {
21277 val = 1;
21278 break;
21279 }
21280 }
21281 // JS specific: little magic to add zero terminator to end of string
21282 if (s.gzindex < s.gzhead.comment.length) {
21283 val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
21284 } else {
21285 val = 0;
21286 }
21287 put_byte(s, val);
21288 } while (val !== 0);
21289
21290 if (s.gzhead.hcrc && s.pending > beg) {
21291 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
21292 }
21293 if (val === 0) {
21294 s.status = HCRC_STATE;
21295 }
21296 }
21297 else {
21298 s.status = HCRC_STATE;
21299 }
21300 }
21301 if (s.status === HCRC_STATE) {
21302 if (s.gzhead.hcrc) {
21303 if (s.pending + 2 > s.pending_buf_size) {
21304 flush_pending(strm);
21305 }
21306 if (s.pending + 2 <= s.pending_buf_size) {
21307 put_byte(s, strm.adler & 0xff);
21308 put_byte(s, (strm.adler >> 8) & 0xff);
21309 strm.adler = 0; //crc32(0L, Z_NULL, 0);
21310 s.status = BUSY_STATE;
21311 }
21312 }
21313 else {
21314 s.status = BUSY_STATE;
21315 }
21316 }
21317 //#endif
21318
21319 /* Flush as much pending output as possible */
21320 if (s.pending !== 0) {
21321 flush_pending(strm);
21322 if (strm.avail_out === 0) {
21323 /* Since avail_out is 0, deflate will be called again with
21324 * more output space, but possibly with both pending and
21325 * avail_in equal to zero. There won't be anything to do,
21326 * but this is not an error situation so make sure we
21327 * return OK instead of BUF_ERROR at next call of deflate:
21328 */
21329 s.last_flush = -1;
21330 return Z_OK;
21331 }
21332
21333 /* Make sure there is something to do and avoid duplicate consecutive
21334 * flushes. For repeated and useless calls with Z_FINISH, we keep
21335 * returning Z_STREAM_END instead of Z_BUF_ERROR.
21336 */
21337 } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
21338 flush !== Z_FINISH) {
21339 return err(strm, Z_BUF_ERROR);
21340 }
21341
21342 /* User must not provide more input after the first FINISH: */
21343 if (s.status === FINISH_STATE && strm.avail_in !== 0) {
21344 return err(strm, Z_BUF_ERROR);
21345 }
21346
21347 /* Start a new block or continue the current one.
21348 */
21349 if (strm.avail_in !== 0 || s.lookahead !== 0 ||
21350 (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
21351 var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
21352 (s.strategy === Z_RLE ? deflate_rle(s, flush) :
21353 configuration_table[s.level].func(s, flush));
21354
21355 if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
21356 s.status = FINISH_STATE;
21357 }
21358 if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
21359 if (strm.avail_out === 0) {
21360 s.last_flush = -1;
21361 /* avoid BUF_ERROR next call, see above */
21362 }
21363 return Z_OK;
21364 /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
21365 * of deflate should use the same flush parameter to make sure
21366 * that the flush is complete. So we don't have to output an
21367 * empty block here, this will be done at next call. This also
21368 * ensures that for a very small output buffer, we emit at most
21369 * one empty block.
21370 */
21371 }
21372 if (bstate === BS_BLOCK_DONE) {
21373 if (flush === Z_PARTIAL_FLUSH) {
21374 _tr_align(s);
21375 }
21376 else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
21377
21378 _tr_stored_block(s, 0, 0, false);
21379 /* For a full flush, this empty block will be recognized
21380 * as a special marker by inflate_sync().
21381 */
21382 if (flush === Z_FULL_FLUSH) {
21383 /*** CLEAR_HASH(s); ***/ /* forget history */
21384 zero$2(s.head); // Fill with NIL (= 0);
21385
21386 if (s.lookahead === 0) {
21387 s.strstart = 0;
21388 s.block_start = 0;
21389 s.insert = 0;
21390 }
21391 }
21392 }
21393 flush_pending(strm);
21394 if (strm.avail_out === 0) {
21395 s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
21396 return Z_OK;
21397 }
21398 }
21399 }
21400 //Assert(strm->avail_out > 0, "bug2");
21401 //if (strm.avail_out <= 0) { throw new Error("bug2");}
21402
21403 if (flush !== Z_FINISH) { return Z_OK; }
21404 if (s.wrap <= 0) { return Z_STREAM_END; }
21405
21406 /* Write the trailer */
21407 if (s.wrap === 2) {
21408 put_byte(s, strm.adler & 0xff);
21409 put_byte(s, (strm.adler >> 8) & 0xff);
21410 put_byte(s, (strm.adler >> 16) & 0xff);
21411 put_byte(s, (strm.adler >> 24) & 0xff);
21412 put_byte(s, strm.total_in & 0xff);
21413 put_byte(s, (strm.total_in >> 8) & 0xff);
21414 put_byte(s, (strm.total_in >> 16) & 0xff);
21415 put_byte(s, (strm.total_in >> 24) & 0xff);
21416 }
21417 else {
21418 putShortMSB(s, strm.adler >>> 16);
21419 putShortMSB(s, strm.adler & 0xffff);
21420 }
21421
21422 flush_pending(strm);
21423 /* If avail_out is zero, the application will call deflate again
21424 * to flush the rest.
21425 */
21426 if (s.wrap > 0) { s.wrap = -s.wrap; }
21427 /* write the trailer only once! */
21428 return s.pending !== 0 ? Z_OK : Z_STREAM_END;
21429}
21430
21431function deflateEnd(strm) {
21432 let status;
21433
21434 if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
21435 return Z_STREAM_ERROR;
21436 }
21437
21438 status = strm.state.status;
21439 if (status !== INIT_STATE &&
21440 status !== EXTRA_STATE &&
21441 status !== NAME_STATE &&
21442 status !== COMMENT_STATE &&
21443 status !== HCRC_STATE &&
21444 status !== BUSY_STATE &&
21445 status !== FINISH_STATE
21446 ) {
21447 return err(strm, Z_STREAM_ERROR);
21448 }
21449
21450 strm.state = null;
21451
21452 return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
21453}
21454
21455
21456/* =========================================================================
21457 * Initializes the compression dictionary from the given byte
21458 * sequence without producing any compressed output.
21459 */
21460function deflateSetDictionary(strm, dictionary) {
21461 const dictLength = dictionary.length;
21462
21463 let s;
21464 let str, n;
21465 let wrap;
21466 let avail;
21467 let next;
21468 let input;
21469 let tmpDict;
21470
21471 if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
21472 return Z_STREAM_ERROR;
21473 }
21474
21475 s = strm.state;
21476 wrap = s.wrap;
21477
21478 if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
21479 return Z_STREAM_ERROR;
21480 }
21481
21482 /* when using zlib wrappers, compute Adler-32 for provided dictionary */
21483 if (wrap === 1) {
21484 /* adler32(strm->adler, dictionary, dictLength); */
21485 strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
21486 }
21487
21488 s.wrap = 0; /* avoid computing Adler-32 in read_buf */
21489
21490 /* if dictionary would fill window, just replace the history */
21491 if (dictLength >= s.w_size) {
21492 if (wrap === 0) { /* already empty otherwise */
21493 /*** CLEAR_HASH(s); ***/
21494 zero$2(s.head); // Fill with NIL (= 0);
21495 s.strstart = 0;
21496 s.block_start = 0;
21497 s.insert = 0;
21498 }
21499 /* use the tail */
21500 // dictionary = dictionary.slice(dictLength - s.w_size);
21501 tmpDict = new Buf8(s.w_size);
21502 arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
21503 dictionary = tmpDict;
21504 dictLength = s.w_size;
21505 }
21506 /* insert dictionary into window and hash */
21507 avail = strm.avail_in;
21508 next = strm.next_in;
21509 input = strm.input;
21510 strm.avail_in = dictLength;
21511 strm.next_in = 0;
21512 strm.input = dictionary;
21513 fill_window(s);
21514 while (s.lookahead >= MIN_MATCH$1) {
21515 str = s.strstart;
21516 n = s.lookahead - (MIN_MATCH$1 - 1);
21517 do {
21518 /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
21519 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH$1 - 1]) & s.hash_mask;
21520
21521 s.prev[str & s.w_mask] = s.head[s.ins_h];
21522
21523 s.head[s.ins_h] = str;
21524 str++;
21525 } while (--n);
21526 s.strstart = str;
21527 s.lookahead = MIN_MATCH$1 - 1;
21528 fill_window(s);
21529 }
21530 s.strstart += s.lookahead;
21531 s.block_start = s.strstart;
21532 s.insert = s.lookahead;
21533 s.lookahead = 0;
21534 s.match_length = s.prev_length = MIN_MATCH$1 - 1;
21535 s.match_available = 0;
21536 strm.next_in = next;
21537 strm.input = input;
21538 strm.avail_in = avail;
21539 s.wrap = wrap;
21540 return Z_OK;
21541}
21542
21543/* Not implemented
21544exports.deflateBound = deflateBound;
21545exports.deflateCopy = deflateCopy;
21546exports.deflateParams = deflateParams;
21547exports.deflatePending = deflatePending;
21548exports.deflatePrime = deflatePrime;
21549exports.deflateTune = deflateTune;
21550*/
21551
21552// String encode/decode helpers
21553
21554try {
21555 String.fromCharCode.apply(null, [ 0 ]);
21556} catch (__) {
21557}
21558try {
21559 String.fromCharCode.apply(null, new Uint8Array(1));
21560} catch (__) {
21561}
21562
21563
21564// Table with utf8 lengths (calculated by first byte of sequence)
21565// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
21566// because max possible codepoint is 0x10ffff
21567const _utf8len = new Buf8(256);
21568for (let q = 0; q < 256; q++) {
21569 _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1;
21570}
21571_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
21572
21573
21574// convert string to array (typed, when possible)
21575function string2buf (str) {
21576 let c, c2, m_pos, i, buf_len = 0;
21577 const str_len = str.length;
21578
21579 // count binary size
21580 for (m_pos = 0; m_pos < str_len; m_pos++) {
21581 c = str.charCodeAt(m_pos);
21582 if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) {
21583 c2 = str.charCodeAt(m_pos + 1);
21584 if ((c2 & 0xfc00) === 0xdc00) {
21585 c = 0x10000 + (c - 0xd800 << 10) + (c2 - 0xdc00);
21586 m_pos++;
21587 }
21588 }
21589 buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
21590 }
21591
21592 // allocate buffer
21593 const buf = new Buf8(buf_len);
21594
21595 // convert
21596 for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
21597 c = str.charCodeAt(m_pos);
21598 if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) {
21599 c2 = str.charCodeAt(m_pos + 1);
21600 if ((c2 & 0xfc00) === 0xdc00) {
21601 c = 0x10000 + (c - 0xd800 << 10) + (c2 - 0xdc00);
21602 m_pos++;
21603 }
21604 }
21605 if (c < 0x80) {
21606 /* one byte */
21607 buf[i++] = c;
21608 } else if (c < 0x800) {
21609 /* two bytes */
21610 buf[i++] = 0xC0 | c >>> 6;
21611 buf[i++] = 0x80 | c & 0x3f;
21612 } else if (c < 0x10000) {
21613 /* three bytes */
21614 buf[i++] = 0xE0 | c >>> 12;
21615 buf[i++] = 0x80 | c >>> 6 & 0x3f;
21616 buf[i++] = 0x80 | c & 0x3f;
21617 } else {
21618 /* four bytes */
21619 buf[i++] = 0xf0 | c >>> 18;
21620 buf[i++] = 0x80 | c >>> 12 & 0x3f;
21621 buf[i++] = 0x80 | c >>> 6 & 0x3f;
21622 buf[i++] = 0x80 | c & 0x3f;
21623 }
21624 }
21625
21626 return buf;
21627}
21628
21629
21630// Convert binary string (typed, when possible)
21631function binstring2buf (str) {
21632 const buf = new Buf8(str.length);
21633 for (let i = 0, len = buf.length; i < len; i++) {
21634 buf[i] = str.charCodeAt(i);
21635 }
21636 return buf;
21637}
21638
21639// (C) 1995-2013 Jean-loup Gailly and Mark Adler
21640// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
21641//
21642// This software is provided 'as-is', without any express or implied
21643// warranty. In no event will the authors be held liable for any damages
21644// arising from the use of this software.
21645//
21646// Permission is granted to anyone to use this software for any purpose,
21647// including commercial applications, and to alter it and redistribute it
21648// freely, subject to the following restrictions:
21649//
21650// 1. The origin of this software must not be misrepresented; you must not
21651// claim that you wrote the original software. If you use this software
21652// in a product, an acknowledgment in the product documentation would be
21653// appreciated but is not required.
21654// 2. Altered source versions must be plainly marked as such, and must not be
21655// misrepresented as being the original software.
21656// 3. This notice may not be removed or altered from any source distribution.
21657
21658class ZStream {
21659 constructor() {
21660 /* next input byte */
21661 this.input = null; // JS specific, because we have no pointers
21662 this.next_in = 0;
21663 /* number of bytes available at input */
21664 this.avail_in = 0;
21665 /* total number of input bytes read so far */
21666 this.total_in = 0;
21667 /* next output byte should be put there */
21668 this.output = null; // JS specific, because we have no pointers
21669 this.next_out = 0;
21670 /* remaining free space at output */
21671 this.avail_out = 0;
21672 /* total number of bytes output so far */
21673 this.total_out = 0;
21674 /* last error message, NULL if no error */
21675 this.msg = ''/*Z_NULL*/;
21676 /* not visible by applications */
21677 this.state = null;
21678 /* best guess about the data type: binary or text */
21679 this.data_type = 2/*Z_UNKNOWN*/;
21680 /* adler32 value of the uncompressed data */
21681 this.adler = 0;
21682 }
21683}
21684
21685/* ===========================================================================*/
21686
21687
21688/**
21689 * class Deflate
21690 *
21691 * Generic JS-style wrapper for zlib calls. If you don't need
21692 * streaming behaviour - use more simple functions: [[deflate]],
21693 * [[deflateRaw]] and [[gzip]].
21694 **/
21695
21696/* internal
21697 * Deflate.chunks -> Array
21698 *
21699 * Chunks of output data, if [[Deflate#onData]] not overridden.
21700 **/
21701
21702/**
21703 * Deflate.result -> Uint8Array|Array
21704 *
21705 * Compressed result, generated by default [[Deflate#onData]]
21706 * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
21707 * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you
21708 * push a chunk with explicit flush (call [[Deflate#push]] with
21709 * `Z_SYNC_FLUSH` param).
21710 **/
21711
21712/**
21713 * Deflate.err -> Number
21714 *
21715 * Error code after deflate finished. 0 (Z_OK) on success.
21716 * You will not need it in real life, because deflate errors
21717 * are possible only on wrong options or bad `onData` / `onEnd`
21718 * custom handlers.
21719 **/
21720
21721/**
21722 * Deflate.msg -> String
21723 *
21724 * Error message, if [[Deflate.err]] != 0
21725 **/
21726
21727
21728/**
21729 * new Deflate(options)
21730 * - options (Object): zlib deflate options.
21731 *
21732 * Creates new deflator instance with specified params. Throws exception
21733 * on bad params. Supported options:
21734 *
21735 * - `level`
21736 * - `windowBits`
21737 * - `memLevel`
21738 * - `strategy`
21739 * - `dictionary`
21740 *
21741 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
21742 * for more information on these.
21743 *
21744 * Additional options, for internal needs:
21745 *
21746 * - `chunkSize` - size of generated data chunks (16K by default)
21747 * - `raw` (Boolean) - do raw deflate
21748 * - `gzip` (Boolean) - create gzip wrapper
21749 * - `to` (String) - if equal to 'string', then result will be "binary string"
21750 * (each char code [0..255])
21751 * - `header` (Object) - custom header for gzip
21752 * - `text` (Boolean) - true if compressed data believed to be text
21753 * - `time` (Number) - modification time, unix timestamp
21754 * - `os` (Number) - operation system code
21755 * - `extra` (Array) - array of bytes with extra data (max 65536)
21756 * - `name` (String) - file name (binary string)
21757 * - `comment` (String) - comment (binary string)
21758 * - `hcrc` (Boolean) - true if header crc should be added
21759 *
21760 * ##### Example:
21761 *
21762 * ```javascript
21763 * var pako = void('pako')
21764 * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
21765 * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
21766 *
21767 * var deflate = new pako.Deflate({ level: 3});
21768 *
21769 * deflate.push(chunk1, false);
21770 * deflate.push(chunk2, true); // true -> last chunk
21771 *
21772 * if (deflate.err) { throw new Error(deflate.err); }
21773 *
21774 * console.log(deflate.result);
21775 * ```
21776 **/
21777
21778class Deflate {
21779 constructor(options) {
21780 this.options = {
21781 level: Z_DEFAULT_COMPRESSION,
21782 method: Z_DEFLATED,
21783 chunkSize: 16384,
21784 windowBits: 15,
21785 memLevel: 8,
21786 strategy: Z_DEFAULT_STRATEGY,
21787 ...(options || {})
21788 };
21789
21790 const opt = this.options;
21791
21792 if (opt.raw && (opt.windowBits > 0)) {
21793 opt.windowBits = -opt.windowBits;
21794 }
21795
21796 else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
21797 opt.windowBits += 16;
21798 }
21799
21800 this.err = 0; // error code, if happens (0 = Z_OK)
21801 this.msg = ''; // error message
21802 this.ended = false; // used to avoid multiple onEnd() calls
21803 this.chunks = []; // chunks of compressed data
21804
21805 this.strm = new ZStream();
21806 this.strm.avail_out = 0;
21807
21808 var status = deflateInit2(
21809 this.strm,
21810 opt.level,
21811 opt.method,
21812 opt.windowBits,
21813 opt.memLevel,
21814 opt.strategy
21815 );
21816
21817 if (status !== Z_OK) {
21818 throw new Error(msg[status]);
21819 }
21820
21821 if (opt.header) {
21822 deflateSetHeader(this.strm, opt.header);
21823 }
21824
21825 if (opt.dictionary) {
21826 let dict;
21827 // Convert data if needed
21828 if (typeof opt.dictionary === 'string') {
21829 // If we need to compress text, change encoding to utf8.
21830 dict = string2buf(opt.dictionary);
21831 } else if (opt.dictionary instanceof ArrayBuffer) {
21832 dict = new Uint8Array(opt.dictionary);
21833 } else {
21834 dict = opt.dictionary;
21835 }
21836
21837 status = deflateSetDictionary(this.strm, dict);
21838
21839 if (status !== Z_OK) {
21840 throw new Error(msg[status]);
21841 }
21842
21843 this._dict_set = true;
21844 }
21845 }
21846
21847 /**
21848 * Deflate#push(data[, mode]) -> Boolean
21849 * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
21850 * converted to utf8 byte sequence.
21851 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
21852 * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
21853 *
21854 * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
21855 * new compressed chunks. Returns `true` on success. The last data block must have
21856 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
21857 * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
21858 * can use mode Z_SYNC_FLUSH, keeping the compression context.
21859 *
21860 * On fail call [[Deflate#onEnd]] with error code and return false.
21861 *
21862 * We strongly recommend to use `Uint8Array` on input for best speed (output
21863 * array format is detected automatically). Also, don't skip last param and always
21864 * use the same type in your code (boolean or number). That will improve JS speed.
21865 *
21866 * For regular `Array`-s make sure all elements are [0..255].
21867 *
21868 * ##### Example
21869 *
21870 * ```javascript
21871 * push(chunk, false); // push one of data chunks
21872 * ...
21873 * push(chunk, true); // push last chunk
21874 * ```
21875 **/
21876 push(data, mode) {
21877 const { strm, options: { chunkSize } } = this;
21878 var status, _mode;
21879
21880 if (this.ended) { return false; }
21881
21882 _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
21883
21884 // Convert data if needed
21885 if (typeof data === 'string') {
21886 // If we need to compress text, change encoding to utf8.
21887 strm.input = string2buf(data);
21888 } else if (data instanceof ArrayBuffer) {
21889 strm.input = new Uint8Array(data);
21890 } else {
21891 strm.input = data;
21892 }
21893
21894 strm.next_in = 0;
21895 strm.avail_in = strm.input.length;
21896
21897 do {
21898 if (strm.avail_out === 0) {
21899 strm.output = new Buf8(chunkSize);
21900 strm.next_out = 0;
21901 strm.avail_out = chunkSize;
21902 }
21903 status = deflate(strm, _mode); /* no bad return value */
21904
21905 if (status !== Z_STREAM_END && status !== Z_OK) {
21906 this.onEnd(status);
21907 this.ended = true;
21908 return false;
21909 }
21910 if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
21911 this.onData(shrinkBuf(strm.output, strm.next_out));
21912 }
21913 } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
21914
21915 // Finalize on the last chunk.
21916 if (_mode === Z_FINISH) {
21917 status = deflateEnd(this.strm);
21918 this.onEnd(status);
21919 this.ended = true;
21920 return status === Z_OK;
21921 }
21922
21923 // callback interim results if Z_SYNC_FLUSH.
21924 if (_mode === Z_SYNC_FLUSH) {
21925 this.onEnd(Z_OK);
21926 strm.avail_out = 0;
21927 return true;
21928 }
21929
21930 return true;
21931 };
21932 /**
21933 * Deflate#onData(chunk) -> Void
21934 * - chunk (Uint8Array|Array|String): output data. Type of array depends
21935 * on js engine support. When string output requested, each chunk
21936 * will be string.
21937 *
21938 * By default, stores data blocks in `chunks[]` property and glue
21939 * those in `onEnd`. Override this handler, if you need another behaviour.
21940 **/
21941 onData(chunk) {
21942 this.chunks.push(chunk);
21943 };
21944
21945 /**
21946 * Deflate#onEnd(status) -> Void
21947 * - status (Number): deflate status. 0 (Z_OK) on success,
21948 * other if not.
21949 *
21950 * Called once after you tell deflate that the input stream is
21951 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
21952 * or if an error happened. By default - join collected chunks,
21953 * free memory and fill `results` / `err` properties.
21954 **/
21955 onEnd(status) {
21956 // On success - join
21957 if (status === Z_OK) {
21958 this.result = flattenChunks(this.chunks);
21959 }
21960 this.chunks = [];
21961 this.err = status;
21962 this.msg = this.strm.msg;
21963 };
21964}
21965
21966// (C) 1995-2013 Jean-loup Gailly and Mark Adler
21967// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
21968//
21969// This software is provided 'as-is', without any express or implied
21970// warranty. In no event will the authors be held liable for any damages
21971// arising from the use of this software.
21972//
21973// Permission is granted to anyone to use this software for any purpose,
21974// including commercial applications, and to alter it and redistribute it
21975// freely, subject to the following restrictions:
21976//
21977// 1. The origin of this software must not be misrepresented; you must not
21978// claim that you wrote the original software. If you use this software
21979// in a product, an acknowledgment in the product documentation would be
21980// appreciated but is not required.
21981// 2. Altered source versions must be plainly marked as such, and must not be
21982// misrepresented as being the original software.
21983// 3. This notice may not be removed or altered from any source distribution.
21984
21985// See state defs from inflate.js
21986const BAD = 30; /* got a data error -- remain here until reset */
21987const TYPE = 12; /* i: waiting for type bits, including last-flag bit */
21988
21989/*
21990 Decode literal, length, and distance codes and write out the resulting
21991 literal and match bytes until either not enough input or output is
21992 available, an end-of-block is encountered, or a data error is encountered.
21993 When large enough input and output buffers are supplied to inflate(), for
21994 example, a 16K input buffer and a 64K output buffer, more than 95% of the
21995 inflate execution time is spent in this routine.
21996
21997 Entry assumptions:
21998
21999 state.mode === LEN
22000 strm.avail_in >= 6
22001 strm.avail_out >= 258
22002 start >= strm.avail_out
22003 state.bits < 8
22004
22005 On return, state.mode is one of:
22006
22007 LEN -- ran out of enough output space or enough available input
22008 TYPE -- reached end of block code, inflate() to interpret next block
22009 BAD -- error in block data
22010
22011 Notes:
22012
22013 - The maximum input bits used by a length/distance pair is 15 bits for the
22014 length code, 5 bits for the length extra, 15 bits for the distance code,
22015 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
22016 Therefore if strm.avail_in >= 6, then there is enough input to avoid
22017 checking for available input while decoding.
22018
22019 - The maximum bytes that a single length/distance pair can output is 258
22020 bytes, which is the maximum length that can be coded. inflate_fast()
22021 requires strm.avail_out >= 258 for each loop to avoid checking for
22022 output space.
22023 */
22024function inflate_fast(strm, start) {
22025 let _in; /* local strm.input */
22026 let _out; /* local strm.output */
22027 // Use `s_window` instead `window`, avoid conflict with instrumentation tools
22028 let hold; /* local strm.hold */
22029 let bits; /* local strm.bits */
22030 let here; /* retrieved table entry */
22031 let op; /* code bits, operation, extra bits, or */
22032 /* window position, window bytes to copy */
22033 let len; /* match length, unused bytes */
22034 let dist; /* match distance */
22035 let from; /* where to copy match from */
22036 let from_source;
22037
22038
22039
22040 /* copy state to local variables */
22041 const state = strm.state;
22042 //here = state.here;
22043 _in = strm.next_in;
22044 const input = strm.input;
22045 const last = _in + (strm.avail_in - 5);
22046 _out = strm.next_out;
22047 const output = strm.output;
22048 const beg = _out - (start - strm.avail_out);
22049 const end = _out + (strm.avail_out - 257);
22050 //#ifdef INFLATE_STRICT
22051 const dmax = state.dmax;
22052 //#endif
22053 const wsize = state.wsize;
22054 const whave = state.whave;
22055 const wnext = state.wnext;
22056 const s_window = state.window;
22057 hold = state.hold;
22058 bits = state.bits;
22059 const lcode = state.lencode;
22060 const dcode = state.distcode;
22061 const lmask = (1 << state.lenbits) - 1;
22062 const dmask = (1 << state.distbits) - 1;
22063
22064
22065 /* decode literals and length/distances until end-of-block or not enough
22066 input data or output space */
22067
22068 top:
22069 do {
22070 if (bits < 15) {
22071 hold += input[_in++] << bits;
22072 bits += 8;
22073 hold += input[_in++] << bits;
22074 bits += 8;
22075 }
22076
22077 here = lcode[hold & lmask];
22078
22079 dolen:
22080 for (;;) { // Goto emulation
22081 op = here >>> 24/*here.bits*/;
22082 hold >>>= op;
22083 bits -= op;
22084 op = here >>> 16 & 0xff/*here.op*/;
22085 if (op === 0) { /* literal */
22086 //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
22087 // "inflate: literal '%c'\n" :
22088 // "inflate: literal 0x%02x\n", here.val));
22089 output[_out++] = here & 0xffff/*here.val*/;
22090 } else if (op & 16) { /* length base */
22091 len = here & 0xffff/*here.val*/;
22092 op &= 15; /* number of extra bits */
22093 if (op) {
22094 if (bits < op) {
22095 hold += input[_in++] << bits;
22096 bits += 8;
22097 }
22098 len += hold & (1 << op) - 1;
22099 hold >>>= op;
22100 bits -= op;
22101 }
22102 //Tracevv((stderr, "inflate: length %u\n", len));
22103 if (bits < 15) {
22104 hold += input[_in++] << bits;
22105 bits += 8;
22106 hold += input[_in++] << bits;
22107 bits += 8;
22108 }
22109 here = dcode[hold & dmask];
22110
22111 dodist:
22112 for (;;) { // goto emulation
22113 op = here >>> 24/*here.bits*/;
22114 hold >>>= op;
22115 bits -= op;
22116 op = here >>> 16 & 0xff/*here.op*/;
22117
22118 if (op & 16) { /* distance base */
22119 dist = here & 0xffff/*here.val*/;
22120 op &= 15; /* number of extra bits */
22121 if (bits < op) {
22122 hold += input[_in++] << bits;
22123 bits += 8;
22124 if (bits < op) {
22125 hold += input[_in++] << bits;
22126 bits += 8;
22127 }
22128 }
22129 dist += hold & (1 << op) - 1;
22130 //#ifdef INFLATE_STRICT
22131 if (dist > dmax) {
22132 strm.msg = "invalid distance too far back";
22133 state.mode = BAD;
22134 break top;
22135 }
22136 //#endif
22137 hold >>>= op;
22138 bits -= op;
22139 //Tracevv((stderr, "inflate: distance %u\n", dist));
22140 op = _out - beg; /* max distance in output */
22141 if (dist > op) { /* see if copy from window */
22142 op = dist - op; /* distance back in window */
22143 if (op > whave) {
22144 if (state.sane) {
22145 strm.msg = "invalid distance too far back";
22146 state.mode = BAD;
22147 break top;
22148 }
22149
22150 // (!) This block is disabled in zlib defaults,
22151 // don't enable it for binary compatibility
22152 //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
22153 // if (len <= op - whave) {
22154 // do {
22155 // output[_out++] = 0;
22156 // } while (--len);
22157 // continue top;
22158 // }
22159 // len -= op - whave;
22160 // do {
22161 // output[_out++] = 0;
22162 // } while (--op > whave);
22163 // if (op === 0) {
22164 // from = _out - dist;
22165 // do {
22166 // output[_out++] = output[from++];
22167 // } while (--len);
22168 // continue top;
22169 // }
22170 //#endif
22171 }
22172 from = 0; // window index
22173 from_source = s_window;
22174 if (wnext === 0) { /* very common case */
22175 from += wsize - op;
22176 if (op < len) { /* some from window */
22177 len -= op;
22178 do {
22179 output[_out++] = s_window[from++];
22180 } while (--op);
22181 from = _out - dist; /* rest from output */
22182 from_source = output;
22183 }
22184 } else if (wnext < op) { /* wrap around window */
22185 from += wsize + wnext - op;
22186 op -= wnext;
22187 if (op < len) { /* some from end of window */
22188 len -= op;
22189 do {
22190 output[_out++] = s_window[from++];
22191 } while (--op);
22192 from = 0;
22193 if (wnext < len) { /* some from start of window */
22194 op = wnext;
22195 len -= op;
22196 do {
22197 output[_out++] = s_window[from++];
22198 } while (--op);
22199 from = _out - dist; /* rest from output */
22200 from_source = output;
22201 }
22202 }
22203 } else { /* contiguous in window */
22204 from += wnext - op;
22205 if (op < len) { /* some from window */
22206 len -= op;
22207 do {
22208 output[_out++] = s_window[from++];
22209 } while (--op);
22210 from = _out - dist; /* rest from output */
22211 from_source = output;
22212 }
22213 }
22214 while (len > 2) {
22215 output[_out++] = from_source[from++];
22216 output[_out++] = from_source[from++];
22217 output[_out++] = from_source[from++];
22218 len -= 3;
22219 }
22220 if (len) {
22221 output[_out++] = from_source[from++];
22222 if (len > 1) {
22223 output[_out++] = from_source[from++];
22224 }
22225 }
22226 } else {
22227 from = _out - dist; /* copy direct from output */
22228 do { /* minimum length is three */
22229 output[_out++] = output[from++];
22230 output[_out++] = output[from++];
22231 output[_out++] = output[from++];
22232 len -= 3;
22233 } while (len > 2);
22234 if (len) {
22235 output[_out++] = output[from++];
22236 if (len > 1) {
22237 output[_out++] = output[from++];
22238 }
22239 }
22240 }
22241 } else if ((op & 64) === 0) { /* 2nd level distance code */
22242 here = dcode[(here & 0xffff)/*here.val*/ + (hold & (1 << op) - 1)];
22243 continue dodist;
22244 } else {
22245 strm.msg = "invalid distance code";
22246 state.mode = BAD;
22247 break top;
22248 }
22249
22250 break; // need to emulate goto via "continue"
22251 }
22252 } else if ((op & 64) === 0) { /* 2nd level length code */
22253 here = lcode[(here & 0xffff)/*here.val*/ + (hold & (1 << op) - 1)];
22254 continue dolen;
22255 } else if (op & 32) { /* end-of-block */
22256 //Tracevv((stderr, "inflate: end of block\n"));
22257 state.mode = TYPE;
22258 break top;
22259 } else {
22260 strm.msg = "invalid literal/length code";
22261 state.mode = BAD;
22262 break top;
22263 }
22264
22265 break; // need to emulate goto via "continue"
22266 }
22267 } while (_in < last && _out < end);
22268
22269 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
22270 len = bits >> 3;
22271 _in -= len;
22272 bits -= len << 3;
22273 hold &= (1 << bits) - 1;
22274
22275 /* update state and return */
22276 strm.next_in = _in;
22277 strm.next_out = _out;
22278 strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
22279 strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);
22280 state.hold = hold;
22281 state.bits = bits;
22282 return;
22283}
22284
22285const MAXBITS = 15;
22286const ENOUGH_LENS = 852;
22287const ENOUGH_DISTS = 592;
22288//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
22289
22290const CODES = 0;
22291const LENS = 1;
22292const DISTS = 2;
22293
22294const lbase = [ /* Length codes 257..285 base */
22295 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
22296 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
22297];
22298
22299const lext = [ /* Length codes 257..285 extra */
22300 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
22301 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
22302];
22303
22304const dbase = [ /* Distance codes 0..29 base */
22305 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
22306 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
22307 8193, 12289, 16385, 24577, 0, 0
22308];
22309
22310const dext = [ /* Distance codes 0..29 extra */
22311 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
22312 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
22313 28, 28, 29, 29, 64, 64
22314];
22315
22316function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) {
22317 const bits = opts.bits;
22318 //here = opts.here; /* table entry for duplication */
22319
22320 let len = 0; /* a code's length in bits */
22321 let sym = 0; /* index of code symbols */
22322 let min = 0, max = 0; /* minimum and maximum code lengths */
22323 let root = 0; /* number of index bits for root table */
22324 let curr = 0; /* number of index bits for current table */
22325 let drop = 0; /* code bits to drop for sub-table */
22326 let left = 0; /* number of prefix codes available */
22327 let used = 0; /* code entries in table used */
22328 let huff = 0; /* Huffman code */
22329 let incr; /* for incrementing code, index */
22330 let fill; /* index for replicating entries */
22331 let low; /* low bits for current root entry */
22332 let next; /* next available space in table */
22333 let base = null; /* base value table to use */
22334 let base_index = 0;
22335 // var shoextra; /* extra bits table to use */
22336 let end; /* use base and extra for symbol > end */
22337 const count = new Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
22338 const offs = new Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
22339 let extra = null;
22340 let extra_index = 0;
22341
22342 let here_bits, here_op, here_val;
22343
22344 /*
22345 Process a set of code lengths to create a canonical Huffman code. The
22346 code lengths are lens[0..codes-1]. Each length corresponds to the
22347 symbols 0..codes-1. The Huffman code is generated by first sorting the
22348 symbols by length from short to long, and retaining the symbol order
22349 for codes with equal lengths. Then the code starts with all zero bits
22350 for the first code of the shortest length, and the codes are integer
22351 increments for the same length, and zeros are appended as the length
22352 increases. For the deflate format, these bits are stored backwards
22353 from their more natural integer increment ordering, and so when the
22354 decoding tables are built in the large loop below, the integer codes
22355 are incremented backwards.
22356
22357 This routine assumes, but does not check, that all of the entries in
22358 lens[] are in the range 0..MAXBITS. The caller must assure this.
22359 1..MAXBITS is interpreted as that code length. zero means that that
22360 symbol does not occur in this code.
22361
22362 The codes are sorted by computing a count of codes for each length,
22363 creating from that a table of starting indices for each length in the
22364 sorted table, and then entering the symbols in order in the sorted
22365 table. The sorted table is work[], with that space being provided by
22366 the caller.
22367
22368 The length counts are used for other purposes as well, i.e. finding
22369 the minimum and maximum length codes, determining if there are any
22370 codes at all, checking for a valid set of lengths, and looking ahead
22371 at length counts to determine sub-table sizes when building the
22372 decoding tables.
22373 */
22374
22375 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
22376 for (len = 0; len <= MAXBITS; len++) {
22377 count[len] = 0;
22378 }
22379 for (sym = 0; sym < codes; sym++) {
22380 count[lens[lens_index + sym]]++;
22381 }
22382
22383 /* bound code lengths, force root to be within code lengths */
22384 root = bits;
22385 for (max = MAXBITS; max >= 1; max--) {
22386 if (count[max] !== 0) {
22387 break;
22388 }
22389 }
22390 if (root > max) {
22391 root = max;
22392 }
22393 if (max === 0) { /* no symbols to code at all */
22394 //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
22395 //table.bits[opts.table_index] = 1; //here.bits = (var char)1;
22396 //table.val[opts.table_index++] = 0; //here.val = (var short)0;
22397 table[table_index++] = 1 << 24 | 64 << 16 | 0;
22398
22399
22400 //table.op[opts.table_index] = 64;
22401 //table.bits[opts.table_index] = 1;
22402 //table.val[opts.table_index++] = 0;
22403 table[table_index++] = 1 << 24 | 64 << 16 | 0;
22404
22405 opts.bits = 1;
22406 return 0; /* no symbols, but wait for decoding to report error */
22407 }
22408 for (min = 1; min < max; min++) {
22409 if (count[min] !== 0) {
22410 break;
22411 }
22412 }
22413 if (root < min) {
22414 root = min;
22415 }
22416
22417 /* check for an over-subscribed or incomplete set of lengths */
22418 left = 1;
22419 for (len = 1; len <= MAXBITS; len++) {
22420 left <<= 1;
22421 left -= count[len];
22422 if (left < 0) {
22423 return -1;
22424 } /* over-subscribed */
22425 }
22426 if (left > 0 && (type === CODES || max !== 1)) {
22427 return -1; /* incomplete set */
22428 }
22429
22430 /* generate offsets into symbol table for each length for sorting */
22431 offs[1] = 0;
22432 for (len = 1; len < MAXBITS; len++) {
22433 offs[len + 1] = offs[len] + count[len];
22434 }
22435
22436 /* sort symbols by length, by symbol order within each length */
22437 for (sym = 0; sym < codes; sym++) {
22438 if (lens[lens_index + sym] !== 0) {
22439 work[offs[lens[lens_index + sym]]++] = sym;
22440 }
22441 }
22442
22443 /*
22444 Create and fill in decoding tables. In this loop, the table being
22445 filled is at next and has curr index bits. The code being used is huff
22446 with length len. That code is converted to an index by dropping drop
22447 bits off of the bottom. For codes where len is less than drop + curr,
22448 those top drop + curr - len bits are incremented through all values to
22449 fill the table with replicated entries.
22450
22451 root is the number of index bits for the root table. When len exceeds
22452 root, sub-tables are created pointed to by the root entry with an index
22453 of the low root bits of huff. This is saved in low to check for when a
22454 new sub-table should be started. drop is zero when the root table is
22455 being filled, and drop is root when sub-tables are being filled.
22456
22457 When a new sub-table is needed, it is necessary to look ahead in the
22458 code lengths to determine what size sub-table is needed. The length
22459 counts are used for this, and so count[] is decremented as codes are
22460 entered in the tables.
22461
22462 used keeps track of how many table entries have been allocated from the
22463 provided *table space. It is checked for LENS and DIST tables against
22464 the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
22465 the initial root table size constants. See the comments in inftrees.h
22466 for more information.
22467
22468 sym increments through all symbols, and the loop terminates when
22469 all codes of length max, i.e. all codes, have been processed. This
22470 routine permits incomplete codes, so another loop after this one fills
22471 in the rest of the decoding tables with invalid code markers.
22472 */
22473
22474 /* set up for code type */
22475 // poor man optimization - use if-else instead of switch,
22476 // to avoid deopts in old v8
22477 if (type === CODES) {
22478 base = extra = work; /* dummy value--not used */
22479 end = 19;
22480
22481 } else if (type === LENS) {
22482 base = lbase;
22483 base_index -= 257;
22484 extra = lext;
22485 extra_index -= 257;
22486 end = 256;
22487
22488 } else { /* DISTS */
22489 base = dbase;
22490 extra = dext;
22491 end = -1;
22492 }
22493
22494 /* initialize opts for loop */
22495 huff = 0; /* starting code */
22496 sym = 0; /* starting code symbol */
22497 len = min; /* starting code length */
22498 next = table_index; /* current table to fill in */
22499 curr = root; /* current table index bits */
22500 drop = 0; /* current bits to drop from code for index */
22501 low = -1; /* trigger new sub-table when len > root */
22502 used = 1 << root; /* use root table entries */
22503 const mask = used - 1; /* mask for comparing low */
22504
22505 /* check available table space */
22506 if (type === LENS && used > ENOUGH_LENS ||
22507 type === DISTS && used > ENOUGH_DISTS) {
22508 return 1;
22509 }
22510
22511 /* process all codes and make table entries */
22512 for (;;) {
22513 /* create table entry */
22514 here_bits = len - drop;
22515 if (work[sym] < end) {
22516 here_op = 0;
22517 here_val = work[sym];
22518 } else if (work[sym] > end) {
22519 here_op = extra[extra_index + work[sym]];
22520 here_val = base[base_index + work[sym]];
22521 } else {
22522 here_op = 32 + 64; /* end of block */
22523 here_val = 0;
22524 }
22525
22526 /* replicate for those indices with low len bits equal to huff */
22527 incr = 1 << len - drop;
22528 fill = 1 << curr;
22529 min = fill; /* save offset to next table */
22530 do {
22531 fill -= incr;
22532 table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val |0;
22533 } while (fill !== 0);
22534
22535 /* backwards increment the len-bit code huff */
22536 incr = 1 << len - 1;
22537 while (huff & incr) {
22538 incr >>= 1;
22539 }
22540 if (incr !== 0) {
22541 huff &= incr - 1;
22542 huff += incr;
22543 } else {
22544 huff = 0;
22545 }
22546
22547 /* go to next symbol, update count, len */
22548 sym++;
22549 if (--count[len] === 0) {
22550 if (len === max) {
22551 break;
22552 }
22553 len = lens[lens_index + work[sym]];
22554 }
22555
22556 /* create new sub-table if needed */
22557 if (len > root && (huff & mask) !== low) {
22558 /* if first time, transition to sub-tables */
22559 if (drop === 0) {
22560 drop = root;
22561 }
22562
22563 /* increment past last table */
22564 next += min; /* here min is 1 << curr */
22565
22566 /* determine length of next table */
22567 curr = len - drop;
22568 left = 1 << curr;
22569 while (curr + drop < max) {
22570 left -= count[curr + drop];
22571 if (left <= 0) {
22572 break;
22573 }
22574 curr++;
22575 left <<= 1;
22576 }
22577
22578 /* check for enough space */
22579 used += 1 << curr;
22580 if (type === LENS && used > ENOUGH_LENS ||
22581 type === DISTS && used > ENOUGH_DISTS) {
22582 return 1;
22583 }
22584
22585 /* point entry in root table to sub-table */
22586 low = huff & mask;
22587 /*table.op[low] = curr;
22588 table.bits[low] = root;
22589 table.val[low] = next - opts.table_index;*/
22590 table[low] = root << 24 | curr << 16 | next - table_index |0;
22591 }
22592 }
22593
22594 /* fill in remaining table entry if code is incomplete (guaranteed to have
22595 at most one remaining entry, since if the code is incomplete, the
22596 maximum code length that was allowed to get this far is one bit) */
22597 if (huff !== 0) {
22598 //table.op[next + huff] = 64; /* invalid code marker */
22599 //table.bits[next + huff] = len - drop;
22600 //table.val[next + huff] = 0;
22601 table[next + huff] = len - drop << 24 | 64 << 16 |0;
22602 }
22603
22604 /* set return parameters */
22605 //opts.table_index += used;
22606 opts.bits = root;
22607 return 0;
22608}
22609
22610const CODES$1 = 0;
22611const LENS$1 = 1;
22612const DISTS$1 = 2;
22613
22614/* STATES ====================================================================*/
22615/* ===========================================================================*/
22616
22617
22618const HEAD = 1; /* i: waiting for magic header */
22619const FLAGS = 2; /* i: waiting for method and flags (gzip) */
22620const TIME = 3; /* i: waiting for modification time (gzip) */
22621const OS = 4; /* i: waiting for extra flags and operating system (gzip) */
22622const EXLEN = 5; /* i: waiting for extra length (gzip) */
22623const EXTRA = 6; /* i: waiting for extra bytes (gzip) */
22624const NAME = 7; /* i: waiting for end of file name (gzip) */
22625const COMMENT = 8; /* i: waiting for end of comment (gzip) */
22626const HCRC = 9; /* i: waiting for header crc (gzip) */
22627const DICTID = 10; /* i: waiting for dictionary check value */
22628const DICT = 11; /* waiting for inflateSetDictionary() call */
22629const TYPE$1 = 12; /* i: waiting for type bits, including last-flag bit */
22630const TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */
22631const STORED = 14; /* i: waiting for stored size (length and complement) */
22632const COPY_ = 15; /* i/o: same as COPY below, but only first time in */
22633const COPY = 16; /* i/o: waiting for input or output to copy stored block */
22634const TABLE = 17; /* i: waiting for dynamic block table lengths */
22635const LENLENS = 18; /* i: waiting for code length code lengths */
22636const CODELENS = 19; /* i: waiting for length/lit and distance code lengths */
22637const LEN_ = 20; /* i: same as LEN below, but only first time in */
22638const LEN = 21; /* i: waiting for length/lit/eob code */
22639const LENEXT = 22; /* i: waiting for length extra bits */
22640const DIST = 23; /* i: waiting for distance code */
22641const DISTEXT = 24; /* i: waiting for distance extra bits */
22642const MATCH = 25; /* o: waiting for output space to copy string */
22643const LIT = 26; /* o: waiting for output space to write literal */
22644const CHECK = 27; /* i: waiting for 32-bit check value */
22645const LENGTH = 28; /* i: waiting for 32-bit length (gzip) */
22646const DONE = 29; /* finished check, done -- remain here until reset */
22647const BAD$1 = 30; /* got a data error -- remain here until reset */
22648//const MEM = 31; /* got an inflate() memory error -- remain here until reset */
22649const SYNC = 32; /* looking for synchronization bytes to restart inflate() */
22650
22651/* ===========================================================================*/
22652
22653
22654
22655const ENOUGH_LENS$1 = 852;
22656const ENOUGH_DISTS$1 = 592;
22657
22658
22659function zswap32(q) {
22660 return (((q >>> 24) & 0xff) +
22661 ((q >>> 8) & 0xff00) +
22662 ((q & 0xff00) << 8) +
22663 ((q & 0xff) << 24));
22664}
22665
22666
22667class InflateState {
22668 constructor() {
22669 this.mode = 0; /* current inflate mode */
22670 this.last = false; /* true if processing last block */
22671 this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
22672 this.havedict = false; /* true if dictionary provided */
22673 this.flags = 0; /* gzip header method and flags (0 if zlib) */
22674 this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
22675 this.check = 0; /* protected copy of check value */
22676 this.total = 0; /* protected copy of output count */
22677 // TODO: may be {}
22678 this.head = null; /* where to save gzip header information */
22679
22680 /* sliding window */
22681 this.wbits = 0; /* log base 2 of requested window size */
22682 this.wsize = 0; /* window size or zero if not using window */
22683 this.whave = 0; /* valid bytes in the window */
22684 this.wnext = 0; /* window write index */
22685 this.window = null; /* allocated sliding window, if needed */
22686
22687 /* bit accumulator */
22688 this.hold = 0; /* input bit accumulator */
22689 this.bits = 0; /* number of bits in "in" */
22690
22691 /* for string and stored block copying */
22692 this.length = 0; /* literal or length of data to copy */
22693 this.offset = 0; /* distance back to copy string from */
22694
22695 /* for table and code decoding */
22696 this.extra = 0; /* extra bits needed */
22697
22698 /* fixed and dynamic code tables */
22699 this.lencode = null; /* starting table for length/literal codes */
22700 this.distcode = null; /* starting table for distance codes */
22701 this.lenbits = 0; /* index bits for lencode */
22702 this.distbits = 0; /* index bits for distcode */
22703
22704 /* dynamic table building */
22705 this.ncode = 0; /* number of code length code lengths */
22706 this.nlen = 0; /* number of length code lengths */
22707 this.ndist = 0; /* number of distance code lengths */
22708 this.have = 0; /* number of code lengths in lens[] */
22709 this.next = null; /* next available space in codes[] */
22710
22711 this.lens = new Buf16(320); /* temporary storage for code lengths */
22712 this.work = new Buf16(288); /* work area for code table building */
22713
22714 /*
22715 because we don't have pointers in js, we use lencode and distcode directly
22716 as buffers so we don't need codes
22717 */
22718 //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */
22719 this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */
22720 this.distdyn = null; /* dynamic table for distance codes (JS specific) */
22721 this.sane = 0; /* if false, allow invalid distance too far */
22722 this.back = 0; /* bits back of last unprocessed length/lit */
22723 this.was = 0; /* initial length of match */
22724 }
22725}
22726
22727function inflateResetKeep(strm) {
22728 let state;
22729
22730 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
22731 state = strm.state;
22732 strm.total_in = strm.total_out = state.total = 0;
22733 strm.msg = ''; /*Z_NULL*/
22734 if (state.wrap) { /* to support ill-conceived Java test suite */
22735 strm.adler = state.wrap & 1;
22736 }
22737 state.mode = HEAD;
22738 state.last = 0;
22739 state.havedict = 0;
22740 state.dmax = 32768;
22741 state.head = null/*Z_NULL*/;
22742 state.hold = 0;
22743 state.bits = 0;
22744 //state.lencode = state.distcode = state.next = state.codes;
22745 state.lencode = state.lendyn = new Buf32(ENOUGH_LENS$1);
22746 state.distcode = state.distdyn = new Buf32(ENOUGH_DISTS$1);
22747
22748 state.sane = 1;
22749 state.back = -1;
22750 //Tracev((stderr, "inflate: reset\n"));
22751 return Z_OK;
22752}
22753
22754function inflateReset(strm) {
22755 let state;
22756
22757 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
22758 state = strm.state;
22759 state.wsize = 0;
22760 state.whave = 0;
22761 state.wnext = 0;
22762 return inflateResetKeep(strm);
22763
22764}
22765
22766function inflateReset2(strm, windowBits) {
22767 let wrap;
22768 let state;
22769
22770 /* get the state */
22771 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
22772 state = strm.state;
22773
22774 /* extract wrap request from windowBits parameter */
22775 if (windowBits < 0) {
22776 wrap = 0;
22777 windowBits = -windowBits;
22778 }
22779 else {
22780 wrap = (windowBits >> 4) + 1;
22781 if (windowBits < 48) {
22782 windowBits &= 15;
22783 }
22784 }
22785
22786 /* set number of window bits, free window if different */
22787 if (windowBits && (windowBits < 8 || windowBits > 15)) {
22788 return Z_STREAM_ERROR;
22789 }
22790 if (state.window !== null && state.wbits !== windowBits) {
22791 state.window = null;
22792 }
22793
22794 /* update state and reset the rest of it */
22795 state.wrap = wrap;
22796 state.wbits = windowBits;
22797 return inflateReset(strm);
22798}
22799
22800function inflateInit2(strm, windowBits) {
22801 let ret;
22802 let state;
22803
22804 if (!strm) { return Z_STREAM_ERROR; }
22805 //strm.msg = Z_NULL; /* in case we return an error */
22806
22807 state = new InflateState();
22808
22809 //if (state === Z_NULL) return Z_MEM_ERROR;
22810 //Tracev((stderr, "inflate: allocated\n"));
22811 strm.state = state;
22812 state.window = null/*Z_NULL*/;
22813 ret = inflateReset2(strm, windowBits);
22814 if (ret !== Z_OK) {
22815 strm.state = null/*Z_NULL*/;
22816 }
22817 return ret;
22818}
22819
22820
22821/*
22822 Return state with length and distance decoding tables and index sizes set to
22823 fixed code decoding. Normally this returns fixed tables from inffixed.h.
22824 If BUILDFIXED is defined, then instead this routine builds the tables the
22825 first time it's called, and returns those tables the first time and
22826 thereafter. This reduces the size of the code by about 2K bytes, in
22827 exchange for a little execution time. However, BUILDFIXED should not be
22828 used for threaded applications, since the rewriting of the tables and virgin
22829 may not be thread-safe.
22830 */
22831let virgin = true;
22832
22833let lenfix, distfix; // We have no pointers in JS, so keep tables separate
22834
22835function fixedtables(state) {
22836 /* build fixed huffman tables if first call (may not be thread safe) */
22837 if (virgin) {
22838 let sym;
22839
22840 lenfix = new Buf32(512);
22841 distfix = new Buf32(32);
22842
22843 /* literal/length table */
22844 sym = 0;
22845 while (sym < 144) { state.lens[sym++] = 8; }
22846 while (sym < 256) { state.lens[sym++] = 9; }
22847 while (sym < 280) { state.lens[sym++] = 7; }
22848 while (sym < 288) { state.lens[sym++] = 8; }
22849
22850 inflate_table(LENS$1, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
22851
22852 /* distance table */
22853 sym = 0;
22854 while (sym < 32) { state.lens[sym++] = 5; }
22855
22856 inflate_table(DISTS$1, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
22857
22858 /* do this just once */
22859 virgin = false;
22860 }
22861
22862 state.lencode = lenfix;
22863 state.lenbits = 9;
22864 state.distcode = distfix;
22865 state.distbits = 5;
22866}
22867
22868
22869/*
22870 Update the window with the last wsize (normally 32K) bytes written before
22871 returning. If window does not exist yet, create it. This is only called
22872 when a window is already in use, or when output has been written during this
22873 inflate call, but the end of the deflate stream has not been reached yet.
22874 It is also called to create a window for dictionary data when a dictionary
22875 is loaded.
22876
22877 Providing output buffers larger than 32K to inflate() should provide a speed
22878 advantage, since only the last 32K of output is copied to the sliding window
22879 upon return from inflate(), and since all distances after the first 32K of
22880 output will fall in the output data, making match copies simpler and faster.
22881 The advantage may be dependent on the size of the processor's data caches.
22882 */
22883function updatewindow(strm, src, end, copy) {
22884 let dist;
22885 const state = strm.state;
22886
22887 /* if it hasn't been done already, allocate space for the window */
22888 if (state.window === null) {
22889 state.wsize = 1 << state.wbits;
22890 state.wnext = 0;
22891 state.whave = 0;
22892
22893 state.window = new Buf8(state.wsize);
22894 }
22895
22896 /* copy state->wsize or less output bytes into the circular window */
22897 if (copy >= state.wsize) {
22898 arraySet(state.window, src, end - state.wsize, state.wsize, 0);
22899 state.wnext = 0;
22900 state.whave = state.wsize;
22901 }
22902 else {
22903 dist = state.wsize - state.wnext;
22904 if (dist > copy) {
22905 dist = copy;
22906 }
22907 //zmemcpy(state->window + state->wnext, end - copy, dist);
22908 arraySet(state.window, src, end - copy, dist, state.wnext);
22909 copy -= dist;
22910 if (copy) {
22911 //zmemcpy(state->window, end - copy, copy);
22912 arraySet(state.window, src, end - copy, copy, 0);
22913 state.wnext = copy;
22914 state.whave = state.wsize;
22915 }
22916 else {
22917 state.wnext += dist;
22918 if (state.wnext === state.wsize) { state.wnext = 0; }
22919 if (state.whave < state.wsize) { state.whave += dist; }
22920 }
22921 }
22922 return 0;
22923}
22924
22925function inflate(strm, flush) {
22926 let state;
22927 let input, output; // input/output buffers
22928 let next; /* next input INDEX */
22929 let put; /* next output INDEX */
22930 let have, left; /* available input and output */
22931 let hold; /* bit buffer */
22932 let bits; /* bits in bit buffer */
22933 let _in, _out; /* save starting available input and output */
22934 let copy; /* number of stored or match bytes to copy */
22935 let from; /* where to copy match bytes from */
22936 let from_source;
22937 let here = 0; /* current decoding table entry */
22938 let here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
22939 //var last; /* parent table entry */
22940 let last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
22941 let len; /* length to copy for repeats, bits to drop */
22942 let ret; /* return code */
22943 let hbuf = new Buf8(4); /* buffer for gzip header crc calculation */
22944 let opts;
22945
22946 let n; // temporary var for NEED_BITS
22947
22948 const order = /* permutation of code lengths */
22949 [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
22950
22951
22952 if (!strm || !strm.state || !strm.output ||
22953 (!strm.input && strm.avail_in !== 0)) {
22954 return Z_STREAM_ERROR;
22955 }
22956
22957 state = strm.state;
22958 if (state.mode === TYPE$1) { state.mode = TYPEDO; } /* skip check */
22959
22960
22961 //--- LOAD() ---
22962 put = strm.next_out;
22963 output = strm.output;
22964 left = strm.avail_out;
22965 next = strm.next_in;
22966 input = strm.input;
22967 have = strm.avail_in;
22968 hold = state.hold;
22969 bits = state.bits;
22970 //---
22971
22972 _in = have;
22973 _out = left;
22974 ret = Z_OK;
22975
22976 inf_leave: // goto emulation
22977 for (;;) {
22978 switch (state.mode) {
22979 case HEAD:
22980 if (state.wrap === 0) {
22981 state.mode = TYPEDO;
22982 break;
22983 }
22984 //=== NEEDBITS(16);
22985 while (bits < 16) {
22986 if (have === 0) { break inf_leave; }
22987 have--;
22988 hold += input[next++] << bits;
22989 bits += 8;
22990 }
22991 //===//
22992 if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */
22993 state.check = 0/*crc32(0L, Z_NULL, 0)*/;
22994 //=== CRC2(state.check, hold);
22995 hbuf[0] = hold & 0xff;
22996 hbuf[1] = (hold >>> 8) & 0xff;
22997 state.check = crc32(state.check, hbuf, 2, 0);
22998 //===//
22999
23000 //=== INITBITS();
23001 hold = 0;
23002 bits = 0;
23003 //===//
23004 state.mode = FLAGS;
23005 break;
23006 }
23007 state.flags = 0; /* expect zlib header */
23008 if (state.head) {
23009 state.head.done = false;
23010 }
23011 if (!(state.wrap & 1) || /* check if zlib header allowed */
23012 (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
23013 strm.msg = 'incorrect header check';
23014 state.mode = BAD$1;
23015 break;
23016 }
23017 if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
23018 strm.msg = 'unknown compression method';
23019 state.mode = BAD$1;
23020 break;
23021 }
23022 //--- DROPBITS(4) ---//
23023 hold >>>= 4;
23024 bits -= 4;
23025 //---//
23026 len = (hold & 0x0f)/*BITS(4)*/ + 8;
23027 if (state.wbits === 0) {
23028 state.wbits = len;
23029 }
23030 else if (len > state.wbits) {
23031 strm.msg = 'invalid window size';
23032 state.mode = BAD$1;
23033 break;
23034 }
23035 state.dmax = 1 << len;
23036 //Tracev((stderr, "inflate: zlib header ok\n"));
23037 strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
23038 state.mode = hold & 0x200 ? DICTID : TYPE$1;
23039 //=== INITBITS();
23040 hold = 0;
23041 bits = 0;
23042 //===//
23043 break;
23044 case FLAGS:
23045 //=== NEEDBITS(16); */
23046 while (bits < 16) {
23047 if (have === 0) { break inf_leave; }
23048 have--;
23049 hold += input[next++] << bits;
23050 bits += 8;
23051 }
23052 //===//
23053 state.flags = hold;
23054 if ((state.flags & 0xff) !== Z_DEFLATED) {
23055 strm.msg = 'unknown compression method';
23056 state.mode = BAD$1;
23057 break;
23058 }
23059 if (state.flags & 0xe000) {
23060 strm.msg = 'unknown header flags set';
23061 state.mode = BAD$1;
23062 break;
23063 }
23064 if (state.head) {
23065 state.head.text = ((hold >> 8) & 1);
23066 }
23067 if (state.flags & 0x0200) {
23068 //=== CRC2(state.check, hold);
23069 hbuf[0] = hold & 0xff;
23070 hbuf[1] = (hold >>> 8) & 0xff;
23071 state.check = crc32(state.check, hbuf, 2, 0);
23072 //===//
23073 }
23074 //=== INITBITS();
23075 hold = 0;
23076 bits = 0;
23077 //===//
23078 state.mode = TIME;
23079 /* falls through */
23080 case TIME:
23081 //=== NEEDBITS(32); */
23082 while (bits < 32) {
23083 if (have === 0) { break inf_leave; }
23084 have--;
23085 hold += input[next++] << bits;
23086 bits += 8;
23087 }
23088 //===//
23089 if (state.head) {
23090 state.head.time = hold;
23091 }
23092 if (state.flags & 0x0200) {
23093 //=== CRC4(state.check, hold)
23094 hbuf[0] = hold & 0xff;
23095 hbuf[1] = (hold >>> 8) & 0xff;
23096 hbuf[2] = (hold >>> 16) & 0xff;
23097 hbuf[3] = (hold >>> 24) & 0xff;
23098 state.check = crc32(state.check, hbuf, 4, 0);
23099 //===
23100 }
23101 //=== INITBITS();
23102 hold = 0;
23103 bits = 0;
23104 //===//
23105 state.mode = OS;
23106 /* falls through */
23107 case OS:
23108 //=== NEEDBITS(16); */
23109 while (bits < 16) {
23110 if (have === 0) { break inf_leave; }
23111 have--;
23112 hold += input[next++] << bits;
23113 bits += 8;
23114 }
23115 //===//
23116 if (state.head) {
23117 state.head.xflags = (hold & 0xff);
23118 state.head.os = (hold >> 8);
23119 }
23120 if (state.flags & 0x0200) {
23121 //=== CRC2(state.check, hold);
23122 hbuf[0] = hold & 0xff;
23123 hbuf[1] = (hold >>> 8) & 0xff;
23124 state.check = crc32(state.check, hbuf, 2, 0);
23125 //===//
23126 }
23127 //=== INITBITS();
23128 hold = 0;
23129 bits = 0;
23130 //===//
23131 state.mode = EXLEN;
23132 /* falls through */
23133 case EXLEN:
23134 if (state.flags & 0x0400) {
23135 //=== NEEDBITS(16); */
23136 while (bits < 16) {
23137 if (have === 0) { break inf_leave; }
23138 have--;
23139 hold += input[next++] << bits;
23140 bits += 8;
23141 }
23142 //===//
23143 state.length = hold;
23144 if (state.head) {
23145 state.head.extra_len = hold;
23146 }
23147 if (state.flags & 0x0200) {
23148 //=== CRC2(state.check, hold);
23149 hbuf[0] = hold & 0xff;
23150 hbuf[1] = (hold >>> 8) & 0xff;
23151 state.check = crc32(state.check, hbuf, 2, 0);
23152 //===//
23153 }
23154 //=== INITBITS();
23155 hold = 0;
23156 bits = 0;
23157 //===//
23158 }
23159 else if (state.head) {
23160 state.head.extra = null/*Z_NULL*/;
23161 }
23162 state.mode = EXTRA;
23163 /* falls through */
23164 case EXTRA:
23165 if (state.flags & 0x0400) {
23166 copy = state.length;
23167 if (copy > have) { copy = have; }
23168 if (copy) {
23169 if (state.head) {
23170 len = state.head.extra_len - state.length;
23171 if (!state.head.extra) {
23172 // Use untyped array for more convenient processing later
23173 state.head.extra = new Array(state.head.extra_len);
23174 }
23175 arraySet(
23176 state.head.extra,
23177 input,
23178 next,
23179 // extra field is limited to 65536 bytes
23180 // - no need for additional size check
23181 copy,
23182 /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
23183 len
23184 );
23185 //zmemcpy(state.head.extra + len, next,
23186 // len + copy > state.head.extra_max ?
23187 // state.head.extra_max - len : copy);
23188 }
23189 if (state.flags & 0x0200) {
23190 state.check = crc32(state.check, input, copy, next);
23191 }
23192 have -= copy;
23193 next += copy;
23194 state.length -= copy;
23195 }
23196 if (state.length) { break inf_leave; }
23197 }
23198 state.length = 0;
23199 state.mode = NAME;
23200 /* falls through */
23201 case NAME:
23202 if (state.flags & 0x0800) {
23203 if (have === 0) { break inf_leave; }
23204 copy = 0;
23205 do {
23206 // TODO: 2 or 1 bytes?
23207 len = input[next + copy++];
23208 /* use constant limit because in js we should not preallocate memory */
23209 if (state.head && len &&
23210 (state.length < 65536 /*state.head.name_max*/)) {
23211 state.head.name += String.fromCharCode(len);
23212 }
23213 } while (len && copy < have);
23214
23215 if (state.flags & 0x0200) {
23216 state.check = crc32(state.check, input, copy, next);
23217 }
23218 have -= copy;
23219 next += copy;
23220 if (len) { break inf_leave; }
23221 }
23222 else if (state.head) {
23223 state.head.name = null;
23224 }
23225 state.length = 0;
23226 state.mode = COMMENT;
23227 /* falls through */
23228 case COMMENT:
23229 if (state.flags & 0x1000) {
23230 if (have === 0) { break inf_leave; }
23231 copy = 0;
23232 do {
23233 len = input[next + copy++];
23234 /* use constant limit because in js we should not preallocate memory */
23235 if (state.head && len &&
23236 (state.length < 65536 /*state.head.comm_max*/)) {
23237 state.head.comment += String.fromCharCode(len);
23238 }
23239 } while (len && copy < have);
23240 if (state.flags & 0x0200) {
23241 state.check = crc32(state.check, input, copy, next);
23242 }
23243 have -= copy;
23244 next += copy;
23245 if (len) { break inf_leave; }
23246 }
23247 else if (state.head) {
23248 state.head.comment = null;
23249 }
23250 state.mode = HCRC;
23251 /* falls through */
23252 case HCRC:
23253 if (state.flags & 0x0200) {
23254 //=== NEEDBITS(16); */
23255 while (bits < 16) {
23256 if (have === 0) { break inf_leave; }
23257 have--;
23258 hold += input[next++] << bits;
23259 bits += 8;
23260 }
23261 //===//
23262 if (hold !== (state.check & 0xffff)) {
23263 strm.msg = 'header crc mismatch';
23264 state.mode = BAD$1;
23265 break;
23266 }
23267 //=== INITBITS();
23268 hold = 0;
23269 bits = 0;
23270 //===//
23271 }
23272 if (state.head) {
23273 state.head.hcrc = ((state.flags >> 9) & 1);
23274 state.head.done = true;
23275 }
23276 strm.adler = state.check = 0;
23277 state.mode = TYPE$1;
23278 break;
23279 case DICTID:
23280 //=== NEEDBITS(32); */
23281 while (bits < 32) {
23282 if (have === 0) { break inf_leave; }
23283 have--;
23284 hold += input[next++] << bits;
23285 bits += 8;
23286 }
23287 //===//
23288 strm.adler = state.check = zswap32(hold);
23289 //=== INITBITS();
23290 hold = 0;
23291 bits = 0;
23292 //===//
23293 state.mode = DICT;
23294 /* falls through */
23295 case DICT:
23296 if (state.havedict === 0) {
23297 //--- RESTORE() ---
23298 strm.next_out = put;
23299 strm.avail_out = left;
23300 strm.next_in = next;
23301 strm.avail_in = have;
23302 state.hold = hold;
23303 state.bits = bits;
23304 //---
23305 return Z_NEED_DICT;
23306 }
23307 strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
23308 state.mode = TYPE$1;
23309 /* falls through */
23310 case TYPE$1:
23311 if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
23312 /* falls through */
23313 case TYPEDO:
23314 if (state.last) {
23315 //--- BYTEBITS() ---//
23316 hold >>>= bits & 7;
23317 bits -= bits & 7;
23318 //---//
23319 state.mode = CHECK;
23320 break;
23321 }
23322 //=== NEEDBITS(3); */
23323 while (bits < 3) {
23324 if (have === 0) { break inf_leave; }
23325 have--;
23326 hold += input[next++] << bits;
23327 bits += 8;
23328 }
23329 //===//
23330 state.last = (hold & 0x01)/*BITS(1)*/;
23331 //--- DROPBITS(1) ---//
23332 hold >>>= 1;
23333 bits -= 1;
23334 //---//
23335
23336 switch ((hold & 0x03)/*BITS(2)*/) {
23337 case 0: /* stored block */
23338 //Tracev((stderr, "inflate: stored block%s\n",
23339 // state.last ? " (last)" : ""));
23340 state.mode = STORED;
23341 break;
23342 case 1: /* fixed block */
23343 fixedtables(state);
23344 //Tracev((stderr, "inflate: fixed codes block%s\n",
23345 // state.last ? " (last)" : ""));
23346 state.mode = LEN_; /* decode codes */
23347 if (flush === Z_TREES) {
23348 //--- DROPBITS(2) ---//
23349 hold >>>= 2;
23350 bits -= 2;
23351 //---//
23352 break inf_leave;
23353 }
23354 break;
23355 case 2: /* dynamic block */
23356 //Tracev((stderr, "inflate: dynamic codes block%s\n",
23357 // state.last ? " (last)" : ""));
23358 state.mode = TABLE;
23359 break;
23360 case 3:
23361 strm.msg = 'invalid block type';
23362 state.mode = BAD$1;
23363 }
23364 //--- DROPBITS(2) ---//
23365 hold >>>= 2;
23366 bits -= 2;
23367 //---//
23368 break;
23369 case STORED:
23370 //--- BYTEBITS() ---// /* go to byte boundary */
23371 hold >>>= bits & 7;
23372 bits -= bits & 7;
23373 //---//
23374 //=== NEEDBITS(32); */
23375 while (bits < 32) {
23376 if (have === 0) { break inf_leave; }
23377 have--;
23378 hold += input[next++] << bits;
23379 bits += 8;
23380 }
23381 //===//
23382 if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
23383 strm.msg = 'invalid stored block lengths';
23384 state.mode = BAD$1;
23385 break;
23386 }
23387 state.length = hold & 0xffff;
23388 //Tracev((stderr, "inflate: stored length %u\n",
23389 // state.length));
23390 //=== INITBITS();
23391 hold = 0;
23392 bits = 0;
23393 //===//
23394 state.mode = COPY_;
23395 if (flush === Z_TREES) { break inf_leave; }
23396 /* falls through */
23397 case COPY_:
23398 state.mode = COPY;
23399 /* falls through */
23400 case COPY:
23401 copy = state.length;
23402 if (copy) {
23403 if (copy > have) { copy = have; }
23404 if (copy > left) { copy = left; }
23405 if (copy === 0) { break inf_leave; }
23406 //--- zmemcpy(put, next, copy); ---
23407 arraySet(output, input, next, copy, put);
23408 //---//
23409 have -= copy;
23410 next += copy;
23411 left -= copy;
23412 put += copy;
23413 state.length -= copy;
23414 break;
23415 }
23416 //Tracev((stderr, "inflate: stored end\n"));
23417 state.mode = TYPE$1;
23418 break;
23419 case TABLE:
23420 //=== NEEDBITS(14); */
23421 while (bits < 14) {
23422 if (have === 0) { break inf_leave; }
23423 have--;
23424 hold += input[next++] << bits;
23425 bits += 8;
23426 }
23427 //===//
23428 state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
23429 //--- DROPBITS(5) ---//
23430 hold >>>= 5;
23431 bits -= 5;
23432 //---//
23433 state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
23434 //--- DROPBITS(5) ---//
23435 hold >>>= 5;
23436 bits -= 5;
23437 //---//
23438 state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
23439 //--- DROPBITS(4) ---//
23440 hold >>>= 4;
23441 bits -= 4;
23442 //---//
23443//#ifndef PKZIP_BUG_WORKAROUND
23444 if (state.nlen > 286 || state.ndist > 30) {
23445 strm.msg = 'too many length or distance symbols';
23446 state.mode = BAD$1;
23447 break;
23448 }
23449//#endif
23450 //Tracev((stderr, "inflate: table sizes ok\n"));
23451 state.have = 0;
23452 state.mode = LENLENS;
23453 /* falls through */
23454 case LENLENS:
23455 while (state.have < state.ncode) {
23456 //=== NEEDBITS(3);
23457 while (bits < 3) {
23458 if (have === 0) { break inf_leave; }
23459 have--;
23460 hold += input[next++] << bits;
23461 bits += 8;
23462 }
23463 //===//
23464 state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
23465 //--- DROPBITS(3) ---//
23466 hold >>>= 3;
23467 bits -= 3;
23468 //---//
23469 }
23470 while (state.have < 19) {
23471 state.lens[order[state.have++]] = 0;
23472 }
23473 // We have separate tables & no pointers. 2 commented lines below not needed.
23474 //state.next = state.codes;
23475 //state.lencode = state.next;
23476 // Switch to use dynamic table
23477 state.lencode = state.lendyn;
23478 state.lenbits = 7;
23479
23480 opts = { bits: state.lenbits };
23481 ret = inflate_table(CODES$1, state.lens, 0, 19, state.lencode, 0, state.work, opts);
23482 state.lenbits = opts.bits;
23483
23484 if (ret) {
23485 strm.msg = 'invalid code lengths set';
23486 state.mode = BAD$1;
23487 break;
23488 }
23489 //Tracev((stderr, "inflate: code lengths ok\n"));
23490 state.have = 0;
23491 state.mode = CODELENS;
23492 /* falls through */
23493 case CODELENS:
23494 while (state.have < state.nlen + state.ndist) {
23495 for (;;) {
23496 here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
23497 here_bits = here >>> 24;
23498 here_op = (here >>> 16) & 0xff;
23499 here_val = here & 0xffff;
23500
23501 if ((here_bits) <= bits) { break; }
23502 //--- PULLBYTE() ---//
23503 if (have === 0) { break inf_leave; }
23504 have--;
23505 hold += input[next++] << bits;
23506 bits += 8;
23507 //---//
23508 }
23509 if (here_val < 16) {
23510 //--- DROPBITS(here.bits) ---//
23511 hold >>>= here_bits;
23512 bits -= here_bits;
23513 //---//
23514 state.lens[state.have++] = here_val;
23515 }
23516 else {
23517 if (here_val === 16) {
23518 //=== NEEDBITS(here.bits + 2);
23519 n = here_bits + 2;
23520 while (bits < n) {
23521 if (have === 0) { break inf_leave; }
23522 have--;
23523 hold += input[next++] << bits;
23524 bits += 8;
23525 }
23526 //===//
23527 //--- DROPBITS(here.bits) ---//
23528 hold >>>= here_bits;
23529 bits -= here_bits;
23530 //---//
23531 if (state.have === 0) {
23532 strm.msg = 'invalid bit length repeat';
23533 state.mode = BAD$1;
23534 break;
23535 }
23536 len = state.lens[state.have - 1];
23537 copy = 3 + (hold & 0x03);//BITS(2);
23538 //--- DROPBITS(2) ---//
23539 hold >>>= 2;
23540 bits -= 2;
23541 //---//
23542 }
23543 else if (here_val === 17) {
23544 //=== NEEDBITS(here.bits + 3);
23545 n = here_bits + 3;
23546 while (bits < n) {
23547 if (have === 0) { break inf_leave; }
23548 have--;
23549 hold += input[next++] << bits;
23550 bits += 8;
23551 }
23552 //===//
23553 //--- DROPBITS(here.bits) ---//
23554 hold >>>= here_bits;
23555 bits -= here_bits;
23556 //---//
23557 len = 0;
23558 copy = 3 + (hold & 0x07);//BITS(3);
23559 //--- DROPBITS(3) ---//
23560 hold >>>= 3;
23561 bits -= 3;
23562 //---//
23563 }
23564 else {
23565 //=== NEEDBITS(here.bits + 7);
23566 n = here_bits + 7;
23567 while (bits < n) {
23568 if (have === 0) { break inf_leave; }
23569 have--;
23570 hold += input[next++] << bits;
23571 bits += 8;
23572 }
23573 //===//
23574 //--- DROPBITS(here.bits) ---//
23575 hold >>>= here_bits;
23576 bits -= here_bits;
23577 //---//
23578 len = 0;
23579 copy = 11 + (hold & 0x7f);//BITS(7);
23580 //--- DROPBITS(7) ---//
23581 hold >>>= 7;
23582 bits -= 7;
23583 //---//
23584 }
23585 if (state.have + copy > state.nlen + state.ndist) {
23586 strm.msg = 'invalid bit length repeat';
23587 state.mode = BAD$1;
23588 break;
23589 }
23590 while (copy--) {
23591 state.lens[state.have++] = len;
23592 }
23593 }
23594 }
23595
23596 /* handle error breaks in while */
23597 if (state.mode === BAD$1) { break; }
23598
23599 /* check for end-of-block code (better have one) */
23600 if (state.lens[256] === 0) {
23601 strm.msg = 'invalid code -- missing end-of-block';
23602 state.mode = BAD$1;
23603 break;
23604 }
23605
23606 /* build code tables -- note: do not change the lenbits or distbits
23607 values here (9 and 6) without reading the comments in inftrees.h
23608 concerning the ENOUGH constants, which depend on those values */
23609 state.lenbits = 9;
23610
23611 opts = { bits: state.lenbits };
23612 ret = inflate_table(LENS$1, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
23613 // We have separate tables & no pointers. 2 commented lines below not needed.
23614 // state.next_index = opts.table_index;
23615 state.lenbits = opts.bits;
23616 // state.lencode = state.next;
23617
23618 if (ret) {
23619 strm.msg = 'invalid literal/lengths set';
23620 state.mode = BAD$1;
23621 break;
23622 }
23623
23624 state.distbits = 6;
23625 //state.distcode.copy(state.codes);
23626 // Switch to use dynamic table
23627 state.distcode = state.distdyn;
23628 opts = { bits: state.distbits };
23629 ret = inflate_table(DISTS$1, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
23630 // We have separate tables & no pointers. 2 commented lines below not needed.
23631 // state.next_index = opts.table_index;
23632 state.distbits = opts.bits;
23633 // state.distcode = state.next;
23634
23635 if (ret) {
23636 strm.msg = 'invalid distances set';
23637 state.mode = BAD$1;
23638 break;
23639 }
23640 //Tracev((stderr, 'inflate: codes ok\n'));
23641 state.mode = LEN_;
23642 if (flush === Z_TREES) { break inf_leave; }
23643 /* falls through */
23644 case LEN_:
23645 state.mode = LEN;
23646 /* falls through */
23647 case LEN:
23648 if (have >= 6 && left >= 258) {
23649 //--- RESTORE() ---
23650 strm.next_out = put;
23651 strm.avail_out = left;
23652 strm.next_in = next;
23653 strm.avail_in = have;
23654 state.hold = hold;
23655 state.bits = bits;
23656 //---
23657 inflate_fast(strm, _out);
23658 //--- LOAD() ---
23659 put = strm.next_out;
23660 output = strm.output;
23661 left = strm.avail_out;
23662 next = strm.next_in;
23663 input = strm.input;
23664 have = strm.avail_in;
23665 hold = state.hold;
23666 bits = state.bits;
23667 //---
23668
23669 if (state.mode === TYPE$1) {
23670 state.back = -1;
23671 }
23672 break;
23673 }
23674 state.back = 0;
23675 for (;;) {
23676 here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/
23677 here_bits = here >>> 24;
23678 here_op = (here >>> 16) & 0xff;
23679 here_val = here & 0xffff;
23680
23681 if (here_bits <= bits) { break; }
23682 //--- PULLBYTE() ---//
23683 if (have === 0) { break inf_leave; }
23684 have--;
23685 hold += input[next++] << bits;
23686 bits += 8;
23687 //---//
23688 }
23689 if (here_op && (here_op & 0xf0) === 0) {
23690 last_bits = here_bits;
23691 last_op = here_op;
23692 last_val = here_val;
23693 for (;;) {
23694 here = state.lencode[last_val +
23695 ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
23696 here_bits = here >>> 24;
23697 here_op = (here >>> 16) & 0xff;
23698 here_val = here & 0xffff;
23699
23700 if ((last_bits + here_bits) <= bits) { break; }
23701 //--- PULLBYTE() ---//
23702 if (have === 0) { break inf_leave; }
23703 have--;
23704 hold += input[next++] << bits;
23705 bits += 8;
23706 //---//
23707 }
23708 //--- DROPBITS(last.bits) ---//
23709 hold >>>= last_bits;
23710 bits -= last_bits;
23711 //---//
23712 state.back += last_bits;
23713 }
23714 //--- DROPBITS(here.bits) ---//
23715 hold >>>= here_bits;
23716 bits -= here_bits;
23717 //---//
23718 state.back += here_bits;
23719 state.length = here_val;
23720 if (here_op === 0) {
23721 //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
23722 // "inflate: literal '%c'\n" :
23723 // "inflate: literal 0x%02x\n", here.val));
23724 state.mode = LIT;
23725 break;
23726 }
23727 if (here_op & 32) {
23728 //Tracevv((stderr, "inflate: end of block\n"));
23729 state.back = -1;
23730 state.mode = TYPE$1;
23731 break;
23732 }
23733 if (here_op & 64) {
23734 strm.msg = 'invalid literal/length code';
23735 state.mode = BAD$1;
23736 break;
23737 }
23738 state.extra = here_op & 15;
23739 state.mode = LENEXT;
23740 /* falls through */
23741 case LENEXT:
23742 if (state.extra) {
23743 //=== NEEDBITS(state.extra);
23744 n = state.extra;
23745 while (bits < n) {
23746 if (have === 0) { break inf_leave; }
23747 have--;
23748 hold += input[next++] << bits;
23749 bits += 8;
23750 }
23751 //===//
23752 state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
23753 //--- DROPBITS(state.extra) ---//
23754 hold >>>= state.extra;
23755 bits -= state.extra;
23756 //---//
23757 state.back += state.extra;
23758 }
23759 //Tracevv((stderr, "inflate: length %u\n", state.length));
23760 state.was = state.length;
23761 state.mode = DIST;
23762 /* falls through */
23763 case DIST:
23764 for (;;) {
23765 here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
23766 here_bits = here >>> 24;
23767 here_op = (here >>> 16) & 0xff;
23768 here_val = here & 0xffff;
23769
23770 if ((here_bits) <= bits) { break; }
23771 //--- PULLBYTE() ---//
23772 if (have === 0) { break inf_leave; }
23773 have--;
23774 hold += input[next++] << bits;
23775 bits += 8;
23776 //---//
23777 }
23778 if ((here_op & 0xf0) === 0) {
23779 last_bits = here_bits;
23780 last_op = here_op;
23781 last_val = here_val;
23782 for (;;) {
23783 here = state.distcode[last_val +
23784 ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
23785 here_bits = here >>> 24;
23786 here_op = (here >>> 16) & 0xff;
23787 here_val = here & 0xffff;
23788
23789 if ((last_bits + here_bits) <= bits) { break; }
23790 //--- PULLBYTE() ---//
23791 if (have === 0) { break inf_leave; }
23792 have--;
23793 hold += input[next++] << bits;
23794 bits += 8;
23795 //---//
23796 }
23797 //--- DROPBITS(last.bits) ---//
23798 hold >>>= last_bits;
23799 bits -= last_bits;
23800 //---//
23801 state.back += last_bits;
23802 }
23803 //--- DROPBITS(here.bits) ---//
23804 hold >>>= here_bits;
23805 bits -= here_bits;
23806 //---//
23807 state.back += here_bits;
23808 if (here_op & 64) {
23809 strm.msg = 'invalid distance code';
23810 state.mode = BAD$1;
23811 break;
23812 }
23813 state.offset = here_val;
23814 state.extra = (here_op) & 15;
23815 state.mode = DISTEXT;
23816 /* falls through */
23817 case DISTEXT:
23818 if (state.extra) {
23819 //=== NEEDBITS(state.extra);
23820 n = state.extra;
23821 while (bits < n) {
23822 if (have === 0) { break inf_leave; }
23823 have--;
23824 hold += input[next++] << bits;
23825 bits += 8;
23826 }
23827 //===//
23828 state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
23829 //--- DROPBITS(state.extra) ---//
23830 hold >>>= state.extra;
23831 bits -= state.extra;
23832 //---//
23833 state.back += state.extra;
23834 }
23835//#ifdef INFLATE_STRICT
23836 if (state.offset > state.dmax) {
23837 strm.msg = 'invalid distance too far back';
23838 state.mode = BAD$1;
23839 break;
23840 }
23841//#endif
23842 //Tracevv((stderr, "inflate: distance %u\n", state.offset));
23843 state.mode = MATCH;
23844 /* falls through */
23845 case MATCH:
23846 if (left === 0) { break inf_leave; }
23847 copy = _out - left;
23848 if (state.offset > copy) { /* copy from window */
23849 copy = state.offset - copy;
23850 if (copy > state.whave) {
23851 if (state.sane) {
23852 strm.msg = 'invalid distance too far back';
23853 state.mode = BAD$1;
23854 break;
23855 }
23856// (!) This block is disabled in zlib defaults,
23857// don't enable it for binary compatibility
23858//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
23859// Trace((stderr, "inflate.c too far\n"));
23860// copy -= state.whave;
23861// if (copy > state.length) { copy = state.length; }
23862// if (copy > left) { copy = left; }
23863// left -= copy;
23864// state.length -= copy;
23865// do {
23866// output[put++] = 0;
23867// } while (--copy);
23868// if (state.length === 0) { state.mode = LEN; }
23869// break;
23870//#endif
23871 }
23872 if (copy > state.wnext) {
23873 copy -= state.wnext;
23874 from = state.wsize - copy;
23875 }
23876 else {
23877 from = state.wnext - copy;
23878 }
23879 if (copy > state.length) { copy = state.length; }
23880 from_source = state.window;
23881 }
23882 else { /* copy from output */
23883 from_source = output;
23884 from = put - state.offset;
23885 copy = state.length;
23886 }
23887 if (copy > left) { copy = left; }
23888 left -= copy;
23889 state.length -= copy;
23890 do {
23891 output[put++] = from_source[from++];
23892 } while (--copy);
23893 if (state.length === 0) { state.mode = LEN; }
23894 break;
23895 case LIT:
23896 if (left === 0) { break inf_leave; }
23897 output[put++] = state.length;
23898 left--;
23899 state.mode = LEN;
23900 break;
23901 case CHECK:
23902 if (state.wrap) {
23903 //=== NEEDBITS(32);
23904 while (bits < 32) {
23905 if (have === 0) { break inf_leave; }
23906 have--;
23907 // Use '|' instead of '+' to make sure that result is signed
23908 hold |= input[next++] << bits;
23909 bits += 8;
23910 }
23911 //===//
23912 _out -= left;
23913 strm.total_out += _out;
23914 state.total += _out;
23915 if (_out) {
23916 strm.adler = state.check =
23917 /*UPDATE(state.check, put - _out, _out);*/
23918 (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
23919
23920 }
23921 _out = left;
23922 // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
23923 if ((state.flags ? hold : zswap32(hold)) !== state.check) {
23924 strm.msg = 'incorrect data check';
23925 state.mode = BAD$1;
23926 break;
23927 }
23928 //=== INITBITS();
23929 hold = 0;
23930 bits = 0;
23931 //===//
23932 //Tracev((stderr, "inflate: check matches trailer\n"));
23933 }
23934 state.mode = LENGTH;
23935 /* falls through */
23936 case LENGTH:
23937 if (state.wrap && state.flags) {
23938 //=== NEEDBITS(32);
23939 while (bits < 32) {
23940 if (have === 0) { break inf_leave; }
23941 have--;
23942 hold += input[next++] << bits;
23943 bits += 8;
23944 }
23945 //===//
23946 if (hold !== (state.total & 0xffffffff)) {
23947 strm.msg = 'incorrect length check';
23948 state.mode = BAD$1;
23949 break;
23950 }
23951 //=== INITBITS();
23952 hold = 0;
23953 bits = 0;
23954 //===//
23955 //Tracev((stderr, "inflate: length matches trailer\n"));
23956 }
23957 state.mode = DONE;
23958 /* falls through */
23959 case DONE:
23960 ret = Z_STREAM_END;
23961 break inf_leave;
23962 case BAD$1:
23963 ret = Z_DATA_ERROR;
23964 break inf_leave;
23965 // case MEM:
23966 // return Z_MEM_ERROR;
23967 case SYNC:
23968 /* falls through */
23969 default:
23970 return Z_STREAM_ERROR;
23971 }
23972 }
23973
23974 // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
23975
23976 /*
23977 Return from inflate(), updating the total counts and the check value.
23978 If there was no progress during the inflate() call, return a buffer
23979 error. Call updatewindow() to create and/or update the window state.
23980 Note: a memory error from inflate() is non-recoverable.
23981 */
23982
23983 //--- RESTORE() ---
23984 strm.next_out = put;
23985 strm.avail_out = left;
23986 strm.next_in = next;
23987 strm.avail_in = have;
23988 state.hold = hold;
23989 state.bits = bits;
23990 //---
23991
23992 if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$1 &&
23993 (state.mode < CHECK || flush !== Z_FINISH))) {
23994 if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ;
23995 }
23996 _in -= strm.avail_in;
23997 _out -= strm.avail_out;
23998 strm.total_in += _in;
23999 strm.total_out += _out;
24000 state.total += _out;
24001 if (state.wrap && _out) {
24002 strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
24003 (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
24004 }
24005 strm.data_type = state.bits + (state.last ? 64 : 0) +
24006 (state.mode === TYPE$1 ? 128 : 0) +
24007 (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
24008 if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
24009 ret = Z_BUF_ERROR;
24010 }
24011 return ret;
24012}
24013
24014function inflateEnd(strm) {
24015
24016 if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
24017 return Z_STREAM_ERROR;
24018 }
24019
24020 const state = strm.state;
24021 if (state.window) {
24022 state.window = null;
24023 }
24024 strm.state = null;
24025 return Z_OK;
24026}
24027
24028function inflateGetHeader(strm, head) {
24029 let state;
24030
24031 /* check state */
24032 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
24033 state = strm.state;
24034 if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
24035
24036 /* save header structure */
24037 state.head = head;
24038 head.done = false;
24039 return Z_OK;
24040}
24041
24042function inflateSetDictionary(strm, dictionary) {
24043 const dictLength = dictionary.length;
24044
24045 let state;
24046 let dictid;
24047
24048 /* check state */
24049 if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
24050 state = strm.state;
24051
24052 if (state.wrap !== 0 && state.mode !== DICT) {
24053 return Z_STREAM_ERROR;
24054 }
24055
24056 /* check for correct dictionary identifier */
24057 if (state.mode === DICT) {
24058 dictid = 1; /* adler32(0, null, 0)*/
24059 /* dictid = adler32(dictid, dictionary, dictLength); */
24060 dictid = adler32(dictid, dictionary, dictLength, 0);
24061 if (dictid !== state.check) {
24062 return Z_DATA_ERROR;
24063 }
24064 }
24065 /* copy dictionary to window using updatewindow(), which will amend the
24066 existing dictionary if appropriate */
24067 updatewindow(strm, dictionary, dictLength, dictLength);
24068 // if (ret) {
24069 // state.mode = MEM;
24070 // return Z_MEM_ERROR;
24071 // }
24072 state.havedict = 1;
24073 // Tracev((stderr, "inflate: dictionary set\n"));
24074 return Z_OK;
24075}
24076
24077/* Not implemented
24078exports.inflateCopy = inflateCopy;
24079exports.inflateGetDictionary = inflateGetDictionary;
24080exports.inflateMark = inflateMark;
24081exports.inflatePrime = inflatePrime;
24082exports.inflateSync = inflateSync;
24083exports.inflateSyncPoint = inflateSyncPoint;
24084exports.inflateUndermine = inflateUndermine;
24085*/
24086
24087// (C) 1995-2013 Jean-loup Gailly and Mark Adler
24088// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
24089//
24090// This software is provided 'as-is', without any express or implied
24091// warranty. In no event will the authors be held liable for any damages
24092// arising from the use of this software.
24093//
24094// Permission is granted to anyone to use this software for any purpose,
24095// including commercial applications, and to alter it and redistribute it
24096// freely, subject to the following restrictions:
24097//
24098// 1. The origin of this software must not be misrepresented; you must not
24099// claim that you wrote the original software. If you use this software
24100// in a product, an acknowledgment in the product documentation would be
24101// appreciated but is not required.
24102// 2. Altered source versions must be plainly marked as such, and must not be
24103// misrepresented as being the original software.
24104// 3. This notice may not be removed or altered from any source distribution.
24105
24106class GZheader {
24107 constructor() {
24108 /* true if compressed data believed to be text */
24109 this.text = 0;
24110 /* modification time */
24111 this.time = 0;
24112 /* extra flags (not used when writing a gzip file) */
24113 this.xflags = 0;
24114 /* operating system */
24115 this.os = 0;
24116 /* pointer to extra field or Z_NULL if none */
24117 this.extra = null;
24118 /* extra field length (valid if extra != Z_NULL) */
24119 this.extra_len = 0; // Actually, we don't need it in JS,
24120 // but leave for few code modifications
24121
24122 //
24123 // Setup limits is not necessary because in js we should not preallocate memory
24124 // for inflate use constant limit in 65536 bytes
24125 //
24126
24127 /* space at extra (only when reading header) */
24128 // this.extra_max = 0;
24129 /* pointer to zero-terminated file name or Z_NULL */
24130 this.name = '';
24131 /* space at name (only when reading header) */
24132 // this.name_max = 0;
24133 /* pointer to zero-terminated comment or Z_NULL */
24134 this.comment = '';
24135 /* space at comment (only when reading header) */
24136 // this.comm_max = 0;
24137 /* true if there was or will be a header crc */
24138 this.hcrc = 0;
24139 /* true when done reading gzip header (not used when writing a gzip file) */
24140 this.done = false;
24141 }
24142}
24143
24144/**
24145 * class Inflate
24146 *
24147 * Generic JS-style wrapper for zlib calls. If you don't need
24148 * streaming behaviour - use more simple functions: [[inflate]]
24149 * and [[inflateRaw]].
24150 **/
24151
24152/* internal
24153 * inflate.chunks -> Array
24154 *
24155 * Chunks of output data, if [[Inflate#onData]] not overridden.
24156 **/
24157
24158/**
24159 * Inflate.result -> Uint8Array|Array|String
24160 *
24161 * Uncompressed result, generated by default [[Inflate#onData]]
24162 * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
24163 * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
24164 * push a chunk with explicit flush (call [[Inflate#push]] with
24165 * `Z_SYNC_FLUSH` param).
24166 **/
24167
24168/**
24169 * Inflate.err -> Number
24170 *
24171 * Error code after inflate finished. 0 (Z_OK) on success.
24172 * Should be checked if broken data possible.
24173 **/
24174
24175/**
24176 * Inflate.msg -> String
24177 *
24178 * Error message, if [[Inflate.err]] != 0
24179 **/
24180
24181
24182/**
24183 * new Inflate(options)
24184 * - options (Object): zlib inflate options.
24185 *
24186 * Creates new inflator instance with specified params. Throws exception
24187 * on bad params. Supported options:
24188 *
24189 * - `windowBits`
24190 * - `dictionary`
24191 *
24192 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
24193 * for more information on these.
24194 *
24195 * Additional options, for internal needs:
24196 *
24197 * - `chunkSize` - size of generated data chunks (16K by default)
24198 * - `raw` (Boolean) - do raw inflate
24199 * - `to` (String) - if equal to 'string', then result will be converted
24200 * from utf8 to utf16 (javascript) string. When string output requested,
24201 * chunk length can differ from `chunkSize`, depending on content.
24202 *
24203 * By default, when no options set, autodetect deflate/gzip data format via
24204 * wrapper header.
24205 *
24206 * ##### Example:
24207 *
24208 * ```javascript
24209 * var pako = void('pako')
24210 * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
24211 * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
24212 *
24213 * var inflate = new pako.Inflate({ level: 3});
24214 *
24215 * inflate.push(chunk1, false);
24216 * inflate.push(chunk2, true); // true -> last chunk
24217 *
24218 * if (inflate.err) { throw new Error(inflate.err); }
24219 *
24220 * console.log(inflate.result);
24221 * ```
24222 **/
24223class Inflate {
24224 constructor(options) {
24225 this.options = {
24226 chunkSize: 16384,
24227 windowBits: 0,
24228 ...(options || {})
24229 };
24230
24231 const opt = this.options;
24232
24233 // Force window size for `raw` data, if not set directly,
24234 // because we have no header for autodetect.
24235 if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
24236 opt.windowBits = -opt.windowBits;
24237 if (opt.windowBits === 0) { opt.windowBits = -15; }
24238 }
24239
24240 // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
24241 if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
24242 !(options && options.windowBits)) {
24243 opt.windowBits += 32;
24244 }
24245
24246 // Gzip header has no info about windows size, we can do autodetect only
24247 // for deflate. So, if window size not set, force it to max when gzip possible
24248 if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
24249 // bit 3 (16) -> gzipped data
24250 // bit 4 (32) -> autodetect gzip/deflate
24251 if ((opt.windowBits & 15) === 0) {
24252 opt.windowBits |= 15;
24253 }
24254 }
24255
24256 this.err = 0; // error code, if happens (0 = Z_OK)
24257 this.msg = ''; // error message
24258 this.ended = false; // used to avoid multiple onEnd() calls
24259 this.chunks = []; // chunks of compressed data
24260
24261 this.strm = new ZStream();
24262 this.strm.avail_out = 0;
24263
24264 let status = inflateInit2(
24265 this.strm,
24266 opt.windowBits
24267 );
24268
24269 if (status !== Z_OK) {
24270 throw new Error(msg[status]);
24271 }
24272
24273 this.header = new GZheader();
24274
24275 inflateGetHeader(this.strm, this.header);
24276
24277 // Setup dictionary
24278 if (opt.dictionary) {
24279 // Convert data if needed
24280 if (typeof opt.dictionary === 'string') {
24281 opt.dictionary = string2buf(opt.dictionary);
24282 } else if (opt.dictionary instanceof ArrayBuffer) {
24283 opt.dictionary = new Uint8Array(opt.dictionary);
24284 }
24285 if (opt.raw) { //In raw mode we need to set the dictionary early
24286 status = inflateSetDictionary(this.strm, opt.dictionary);
24287 if (status !== Z_OK) {
24288 throw new Error(msg[status]);
24289 }
24290 }
24291 }
24292 }
24293 /**
24294 * Inflate#push(data[, mode]) -> Boolean
24295 * - data (Uint8Array|Array|ArrayBuffer|String): input data
24296 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
24297 * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
24298 *
24299 * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
24300 * new output chunks. Returns `true` on success. The last data block must have
24301 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
24302 * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
24303 * can use mode Z_SYNC_FLUSH, keeping the decompression context.
24304 *
24305 * On fail call [[Inflate#onEnd]] with error code and return false.
24306 *
24307 * We strongly recommend to use `Uint8Array` on input for best speed (output
24308 * format is detected automatically). Also, don't skip last param and always
24309 * use the same type in your code (boolean or number). That will improve JS speed.
24310 *
24311 * For regular `Array`-s make sure all elements are [0..255].
24312 *
24313 * ##### Example
24314 *
24315 * ```javascript
24316 * push(chunk, false); // push one of data chunks
24317 * ...
24318 * push(chunk, true); // push last chunk
24319 * ```
24320 **/
24321 push(data, mode) {
24322 const { strm, options: { chunkSize, dictionary } } = this;
24323 let status, _mode;
24324
24325 // Flag to properly process Z_BUF_ERROR on testing inflate call
24326 // when we check that all output data was flushed.
24327 let allowBufError = false;
24328
24329 if (this.ended) { return false; }
24330 _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
24331
24332 // Convert data if needed
24333 if (typeof data === 'string') {
24334 // Only binary strings can be decompressed on practice
24335 strm.input = binstring2buf(data);
24336 } else if (data instanceof ArrayBuffer) {
24337 strm.input = new Uint8Array(data);
24338 } else {
24339 strm.input = data;
24340 }
24341
24342 strm.next_in = 0;
24343 strm.avail_in = strm.input.length;
24344
24345 do {
24346 if (strm.avail_out === 0) {
24347 strm.output = new Buf8(chunkSize);
24348 strm.next_out = 0;
24349 strm.avail_out = chunkSize;
24350 }
24351
24352 status = inflate(strm, Z_NO_FLUSH); /* no bad return value */
24353
24354 if (status === Z_NEED_DICT && dictionary) {
24355 status = inflateSetDictionary(this.strm, dictionary);
24356 }
24357
24358 if (status === Z_BUF_ERROR && allowBufError === true) {
24359 status = Z_OK;
24360 allowBufError = false;
24361 }
24362
24363 if (status !== Z_STREAM_END && status !== Z_OK) {
24364 this.onEnd(status);
24365 this.ended = true;
24366 return false;
24367 }
24368
24369 if (strm.next_out) {
24370 if (strm.avail_out === 0 || status === Z_STREAM_END || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
24371 this.onData(shrinkBuf(strm.output, strm.next_out));
24372 }
24373 }
24374
24375 // When no more input data, we should check that internal inflate buffers
24376 // are flushed. The only way to do it when avail_out = 0 - run one more
24377 // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
24378 // Here we set flag to process this error properly.
24379 //
24380 // NOTE. Deflate does not return error in this case and does not needs such
24381 // logic.
24382 if (strm.avail_in === 0 && strm.avail_out === 0) {
24383 allowBufError = true;
24384 }
24385
24386 } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
24387
24388 if (status === Z_STREAM_END) {
24389 _mode = Z_FINISH;
24390 }
24391
24392 // Finalize on the last chunk.
24393 if (_mode === Z_FINISH) {
24394 status = inflateEnd(this.strm);
24395 this.onEnd(status);
24396 this.ended = true;
24397 return status === Z_OK;
24398 }
24399
24400 // callback interim results if Z_SYNC_FLUSH.
24401 if (_mode === Z_SYNC_FLUSH) {
24402 this.onEnd(Z_OK);
24403 strm.avail_out = 0;
24404 return true;
24405 }
24406
24407 return true;
24408 };
24409
24410 /**
24411 * Inflate#onData(chunk) -> Void
24412 * - chunk (Uint8Array|Array|String): output data. Type of array depends
24413 * on js engine support. When string output requested, each chunk
24414 * will be string.
24415 *
24416 * By default, stores data blocks in `chunks[]` property and glue
24417 * those in `onEnd`. Override this handler, if you need another behaviour.
24418 **/
24419 onData(chunk) {
24420 this.chunks.push(chunk);
24421 };
24422
24423
24424
24425 /**
24426 * Inflate#onEnd(status) -> Void
24427 * - status (Number): inflate status. 0 (Z_OK) on success,
24428 * other if not.
24429 *
24430 * Called either after you tell inflate that the input stream is
24431 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
24432 * or if an error happened. By default - join collected chunks,
24433 * free memory and fill `results` / `err` properties.
24434 **/
24435 onEnd(status) {
24436 // On success - join
24437 if (status === Z_OK) {
24438 this.result = flattenChunks(this.chunks);
24439 }
24440 this.chunks = [];
24441 this.err = status;
24442 this.msg = this.strm.msg;
24443 };
24444}
24445
24446/*
24447node-bzip - a pure-javascript Node.JS module for decoding bzip2 data
24448
24449Copyright (C) 2012 Eli Skeggs
24450
24451This library is free software; you can redistribute it and/or
24452modify it under the terms of the GNU Lesser General Public
24453License as published by the Free Software Foundation; either
24454version 2.1 of the License, or (at your option) any later version.
24455
24456This library is distributed in the hope that it will be useful,
24457but WITHOUT ANY WARRANTY; without even the implied warranty of
24458MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24459Lesser General Public License for more details.
24460
24461You should have received a copy of the GNU Lesser General Public
24462License along with this library; if not, see
24463http://www.gnu.org/licenses/lgpl-2.1.html
24464
24465Adapted from bzip2.js, copyright 2011 antimatter15 (antimatter15@gmail.com).
24466
24467Based on micro-bunzip by Rob Landley (rob@landley.net).
24468
24469Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
24470which also acknowledges contributions by Mike Burrows, David Wheeler,
24471Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
24472Robert Sedgewick, and Jon L. Bentley.
24473*/
24474
24475var BITMASK = [0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF];
24476
24477// offset in bytes
24478var BitReader = function(stream) {
24479 this.stream = stream;
24480 this.bitOffset = 0;
24481 this.curByte = 0;
24482 this.hasByte = false;
24483};
24484
24485BitReader.prototype._ensureByte = function() {
24486 if (!this.hasByte) {
24487 this.curByte = this.stream.readByte();
24488 this.hasByte = true;
24489 }
24490};
24491
24492// reads bits from the buffer
24493BitReader.prototype.read = function(bits) {
24494 var result = 0;
24495 while (bits > 0) {
24496 this._ensureByte();
24497 var remaining = 8 - this.bitOffset;
24498 // if we're in a byte
24499 if (bits >= remaining) {
24500 result <<= remaining;
24501 result |= BITMASK[remaining] & this.curByte;
24502 this.hasByte = false;
24503 this.bitOffset = 0;
24504 bits -= remaining;
24505 } else {
24506 result <<= bits;
24507 var shift = remaining - bits;
24508 result |= (this.curByte & (BITMASK[bits] << shift)) >> shift;
24509 this.bitOffset += bits;
24510 bits = 0;
24511 }
24512 }
24513 return result;
24514};
24515
24516// seek to an arbitrary point in the buffer (expressed in bits)
24517BitReader.prototype.seek = function(pos) {
24518 var n_bit = pos % 8;
24519 var n_byte = (pos - n_bit) / 8;
24520 this.bitOffset = n_bit;
24521 this.stream.seek(n_byte);
24522 this.hasByte = false;
24523};
24524
24525// reads 6 bytes worth of data using the read method
24526BitReader.prototype.pi = function() {
24527 var buf = new Uint8Array(6), i;
24528 for (i = 0; i < buf.length; i++) {
24529 buf[i] = this.read(8);
24530 }
24531 return bufToHex(buf);
24532};
24533
24534function bufToHex(buf) {
24535 return Array.prototype.map.call(buf, x => ('00' + x.toString(16)).slice(-2)).join('');
24536}
24537
24538var bitreader = BitReader;
24539
24540/* very simple input/output stream interface */
24541var Stream = function() {
24542};
24543
24544// input streams //////////////
24545/** Returns the next byte, or -1 for EOF. */
24546Stream.prototype.readByte = function() {
24547 throw new Error("abstract method readByte() not implemented");
24548};
24549/** Attempts to fill the buffer; returns number of bytes read, or
24550 * -1 for EOF. */
24551Stream.prototype.read = function(buffer, bufOffset, length) {
24552 var bytesRead = 0;
24553 while (bytesRead < length) {
24554 var c = this.readByte();
24555 if (c < 0) { // EOF
24556 return (bytesRead===0) ? -1 : bytesRead;
24557 }
24558 buffer[bufOffset++] = c;
24559 bytesRead++;
24560 }
24561 return bytesRead;
24562};
24563Stream.prototype.seek = function(new_pos) {
24564 throw new Error("abstract method seek() not implemented");
24565};
24566
24567// output streams ///////////
24568Stream.prototype.writeByte = function(_byte) {
24569 throw new Error("abstract method readByte() not implemented");
24570};
24571Stream.prototype.write = function(buffer, bufOffset, length) {
24572 var i;
24573 for (i=0; i<length; i++) {
24574 this.writeByte(buffer[bufOffset++]);
24575 }
24576 return length;
24577};
24578Stream.prototype.flush = function() {
24579};
24580
24581var stream$1 = Stream;
24582
24583/* CRC32, used in Bzip2 implementation.
24584 * This is a port of CRC32.java from the jbzip2 implementation at
24585 * https://code.google.com/p/jbzip2
24586 * which is:
24587 * Copyright (c) 2011 Matthew Francis
24588 *
24589 * Permission is hereby granted, free of charge, to any person
24590 * obtaining a copy of this software and associated documentation
24591 * files (the "Software"), to deal in the Software without
24592 * restriction, including without limitation the rights to use,
24593 * copy, modify, merge, publish, distribute, sublicense, and/or sell
24594 * copies of the Software, and to permit persons to whom the
24595 * Software is furnished to do so, subject to the following
24596 * conditions:
24597 *
24598 * The above copyright notice and this permission notice shall be
24599 * included in all copies or substantial portions of the Software.
24600 *
24601 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24602 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
24603 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24604 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24605 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24606 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24607 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24608 * OTHER DEALINGS IN THE SOFTWARE.
24609 * This JavaScript implementation is:
24610 * Copyright (c) 2013 C. Scott Ananian
24611 * with the same licensing terms as Matthew Francis' original implementation.
24612 */
24613var crc32$1 = (function() {
24614
24615 /**
24616 * A static CRC lookup table
24617 */
24618 var crc32Lookup = new Uint32Array([
24619 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
24620 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
24621 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
24622 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
24623 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
24624 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
24625 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
24626 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
24627 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
24628 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
24629 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
24630 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
24631 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
24632 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
24633 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
24634 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
24635 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
24636 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
24637 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
24638 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
24639 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
24640 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
24641 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
24642 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
24643 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
24644 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
24645 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
24646 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
24647 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
24648 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
24649 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
24650 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
24651 ]);
24652
24653 var CRC32 = function() {
24654 /**
24655 * The current CRC
24656 */
24657 var crc = 0xffffffff;
24658
24659 /**
24660 * @return The current CRC
24661 */
24662 this.getCRC = function() {
24663 return (~crc) >>> 0; // return an unsigned value
24664 };
24665
24666 /**
24667 * Update the CRC with a single byte
24668 * @param value The value to update the CRC with
24669 */
24670 this.updateCRC = function(value) {
24671 crc = (crc << 8) ^ crc32Lookup[((crc >>> 24) ^ value) & 0xff];
24672 };
24673
24674 /**
24675 * Update the CRC with a sequence of identical bytes
24676 * @param value The value to update the CRC with
24677 * @param count The number of bytes
24678 */
24679 this.updateCRCRun = function(value, count) {
24680 while (count-- > 0) {
24681 crc = (crc << 8) ^ crc32Lookup[((crc >>> 24) ^ value) & 0xff];
24682 }
24683 };
24684 };
24685 return CRC32;
24686})();
24687
24688/*
24689seek-bzip - a pure-javascript module for seeking within bzip2 data
24690
24691Copyright (C) 2013 C. Scott Ananian
24692Copyright (C) 2012 Eli Skeggs
24693Copyright (C) 2011 Kevin Kwok
24694
24695This library is free software; you can redistribute it and/or
24696modify it under the terms of the GNU Lesser General Public
24697License as published by the Free Software Foundation; either
24698version 2.1 of the License, or (at your option) any later version.
24699
24700This library is distributed in the hope that it will be useful,
24701but WITHOUT ANY WARRANTY; without even the implied warranty of
24702MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24703Lesser General Public License for more details.
24704
24705You should have received a copy of the GNU Lesser General Public
24706License along with this library; if not, see
24707http://www.gnu.org/licenses/lgpl-2.1.html
24708
24709Adapted from node-bzip, copyright 2012 Eli Skeggs.
24710Adapted from bzip2.js, copyright 2011 Kevin Kwok (antimatter15@gmail.com).
24711
24712Based on micro-bunzip by Rob Landley (rob@landley.net).
24713
24714Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
24715which also acknowledges contributions by Mike Burrows, David Wheeler,
24716Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
24717Robert Sedgewick, and Jon L. Bentley.
24718*/
24719
24720
24721
24722
24723
24724var MAX_HUFCODE_BITS = 20;
24725var MAX_SYMBOLS = 258;
24726var SYMBOL_RUNA = 0;
24727var SYMBOL_RUNB = 1;
24728var MIN_GROUPS = 2;
24729var MAX_GROUPS = 6;
24730var GROUP_SIZE = 50;
24731
24732var WHOLEPI = "314159265359";
24733var SQRTPI = "177245385090";
24734
24735var mtf = function(array, index) {
24736 var src = array[index], i;
24737 for (i = index; i > 0; i--) {
24738 array[i] = array[i-1];
24739 }
24740 array[0] = src;
24741 return src;
24742};
24743
24744var Err = {
24745 OK: 0,
24746 LAST_BLOCK: -1,
24747 NOT_BZIP_DATA: -2,
24748 UNEXPECTED_INPUT_EOF: -3,
24749 UNEXPECTED_OUTPUT_EOF: -4,
24750 DATA_ERROR: -5,
24751 OUT_OF_MEMORY: -6,
24752 OBSOLETE_INPUT: -7,
24753 END_OF_BLOCK: -8
24754};
24755var ErrorMessages = {};
24756ErrorMessages[Err.LAST_BLOCK] = "Bad file checksum";
24757ErrorMessages[Err.NOT_BZIP_DATA] = "Not bzip data";
24758ErrorMessages[Err.UNEXPECTED_INPUT_EOF] = "Unexpected input EOF";
24759ErrorMessages[Err.UNEXPECTED_OUTPUT_EOF] = "Unexpected output EOF";
24760ErrorMessages[Err.DATA_ERROR] = "Data error";
24761ErrorMessages[Err.OUT_OF_MEMORY] = "Out of memory";
24762ErrorMessages[Err.OBSOLETE_INPUT] = "Obsolete (pre 0.9.5) bzip format not supported.";
24763
24764var _throw = function(status, optDetail) {
24765 var msg = ErrorMessages[status] || 'unknown error';
24766 if (optDetail) { msg += ': '+optDetail; }
24767 var e = new TypeError(msg);
24768 e.errorCode = status;
24769 throw e;
24770};
24771
24772var Bunzip = function(inputStream, outputStream) {
24773 this.writePos = this.writeCurrent = this.writeCount = 0;
24774
24775 this._start_bunzip(inputStream, outputStream);
24776};
24777Bunzip.prototype._init_block = function() {
24778 var moreBlocks = this._get_next_block();
24779 if ( !moreBlocks ) {
24780 this.writeCount = -1;
24781 return false; /* no more blocks */
24782 }
24783 this.blockCRC = new crc32$1();
24784 return true;
24785};
24786/* XXX micro-bunzip uses (inputStream, inputBuffer, len) as arguments */
24787Bunzip.prototype._start_bunzip = function(inputStream, outputStream) {
24788 /* Ensure that file starts with "BZh['1'-'9']." */
24789 var buf = new Uint8Array(4);
24790 if (inputStream.read(buf, 0, 4) !== 4 ||
24791 String.fromCharCode(buf[0], buf[1], buf[2]) !== 'BZh')
24792 _throw(Err.NOT_BZIP_DATA, 'bad magic');
24793
24794 var level = buf[3] - 0x30;
24795 if (level < 1 || level > 9)
24796 _throw(Err.NOT_BZIP_DATA, 'level out of range');
24797
24798 this.reader = new bitreader(inputStream);
24799
24800 /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
24801 uncompressed data. Allocate intermediate buffer for block. */
24802 this.dbufSize = 100000 * level;
24803 this.nextoutput = 0;
24804 this.outputStream = outputStream;
24805 this.streamCRC = 0;
24806};
24807Bunzip.prototype._get_next_block = function() {
24808 var i, j, k;
24809 var reader = this.reader;
24810 // this is get_next_block() function from micro-bunzip:
24811 /* Read in header signature and CRC, then validate signature.
24812 (last block signature means CRC is for whole file, return now) */
24813 var h = reader.pi();
24814 if (h === SQRTPI) { // last block
24815 return false; /* no more blocks */
24816 }
24817 if (h !== WHOLEPI)
24818 _throw(Err.NOT_BZIP_DATA);
24819 this.targetBlockCRC = reader.read(32) >>> 0; // (convert to unsigned)
24820 this.streamCRC = (this.targetBlockCRC ^
24821 ((this.streamCRC << 1) | (this.streamCRC>>>31))) >>> 0;
24822 /* We can add support for blockRandomised if anybody complains. There was
24823 some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
24824 it didn't actually work. */
24825 if (reader.read(1))
24826 _throw(Err.OBSOLETE_INPUT);
24827 var origPointer = reader.read(24);
24828 if (origPointer > this.dbufSize)
24829 _throw(Err.DATA_ERROR, 'initial position out of bounds');
24830 /* mapping table: if some byte values are never used (encoding things
24831 like ascii text), the compression code removes the gaps to have fewer
24832 symbols to deal with, and writes a sparse bitfield indicating which
24833 values were present. We make a translation table to convert the symbols
24834 back to the corresponding bytes. */
24835 var t = reader.read(16);
24836 var symToByte = new Uint8Array(256), symTotal = 0;
24837 for (i = 0; i < 16; i++) {
24838 if (t & (1 << (0xF - i))) {
24839 var o = i * 16;
24840 k = reader.read(16);
24841 for (j = 0; j < 16; j++)
24842 if (k & (1 << (0xF - j)))
24843 symToByte[symTotal++] = o + j;
24844 }
24845 }
24846
24847 /* How many different huffman coding groups does this block use? */
24848 var groupCount = reader.read(3);
24849 if (groupCount < MIN_GROUPS || groupCount > MAX_GROUPS)
24850 _throw(Err.DATA_ERROR);
24851 /* nSelectors: Every GROUP_SIZE many symbols we select a new huffman coding
24852 group. Read in the group selector list, which is stored as MTF encoded
24853 bit runs. (MTF=Move To Front, as each value is used it's moved to the
24854 start of the list.) */
24855 var nSelectors = reader.read(15);
24856 if (nSelectors === 0)
24857 _throw(Err.DATA_ERROR);
24858
24859 var mtfSymbol = new Uint8Array(256);
24860 for (i = 0; i < groupCount; i++)
24861 mtfSymbol[i] = i;
24862
24863 var selectors = new Uint8Array(nSelectors); // was 32768...
24864
24865 for (i = 0; i < nSelectors; i++) {
24866 /* Get next value */
24867 for (j = 0; reader.read(1); j++)
24868 if (j >= groupCount) _throw(Err.DATA_ERROR);
24869 /* Decode MTF to get the next selector */
24870 selectors[i] = mtf(mtfSymbol, j);
24871 }
24872
24873 /* Read the huffman coding tables for each group, which code for symTotal
24874 literal symbols, plus two run symbols (RUNA, RUNB) */
24875 var symCount = symTotal + 2;
24876 var groups = [], hufGroup;
24877 for (j = 0; j < groupCount; j++) {
24878 var length = new Uint8Array(symCount), temp = new Uint16Array(MAX_HUFCODE_BITS + 1);
24879 /* Read huffman code lengths for each symbol. They're stored in
24880 a way similar to mtf; record a starting value for the first symbol,
24881 and an offset from the previous value for everys symbol after that. */
24882 t = reader.read(5); // lengths
24883 for (i = 0; i < symCount; i++) {
24884 for (;;) {
24885 if (t < 1 || t > MAX_HUFCODE_BITS) _throw(Err.DATA_ERROR);
24886 /* If first bit is 0, stop. Else second bit indicates whether
24887 to increment or decrement the value. */
24888 if(!reader.read(1))
24889 break;
24890 if(!reader.read(1))
24891 t++;
24892 else
24893 t--;
24894 }
24895 length[i] = t;
24896 }
24897
24898 /* Find largest and smallest lengths in this group */
24899 var minLen, maxLen;
24900 minLen = maxLen = length[0];
24901 for (i = 1; i < symCount; i++) {
24902 if (length[i] > maxLen)
24903 maxLen = length[i];
24904 else if (length[i] < minLen)
24905 minLen = length[i];
24906 }
24907
24908 /* Calculate permute[], base[], and limit[] tables from length[].
24909 *
24910 * permute[] is the lookup table for converting huffman coded symbols
24911 * into decoded symbols. base[] is the amount to subtract from the
24912 * value of a huffman symbol of a given length when using permute[].
24913 *
24914 * limit[] indicates the largest numerical value a symbol with a given
24915 * number of bits can have. This is how the huffman codes can vary in
24916 * length: each code with a value>limit[length] needs another bit.
24917 */
24918 hufGroup = {};
24919 groups.push(hufGroup);
24920 hufGroup.permute = new Uint16Array(MAX_SYMBOLS);
24921 hufGroup.limit = new Uint32Array(MAX_HUFCODE_BITS + 2);
24922 hufGroup.base = new Uint32Array(MAX_HUFCODE_BITS + 1);
24923 hufGroup.minLen = minLen;
24924 hufGroup.maxLen = maxLen;
24925 /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */
24926 var pp = 0;
24927 for (i = minLen; i <= maxLen; i++) {
24928 temp[i] = hufGroup.limit[i] = 0;
24929 for (t = 0; t < symCount; t++)
24930 if (length[t] === i)
24931 hufGroup.permute[pp++] = t;
24932 }
24933 /* Count symbols coded for at each bit length */
24934 for (i = 0; i < symCount; i++)
24935 temp[length[i]]++;
24936 /* Calculate limit[] (the largest symbol-coding value at each bit
24937 * length, which is (previous limit<<1)+symbols at this level), and
24938 * base[] (number of symbols to ignore at each bit length, which is
24939 * limit minus the cumulative count of symbols coded for already). */
24940 pp = t = 0;
24941 for (i = minLen; i < maxLen; i++) {
24942 pp += temp[i];
24943 /* We read the largest possible symbol size and then unget bits
24944 after determining how many we need, and those extra bits could
24945 be set to anything. (They're noise from future symbols.) At
24946 each level we're really only interested in the first few bits,
24947 so here we set all the trailing to-be-ignored bits to 1 so they
24948 don't affect the value>limit[length] comparison. */
24949 hufGroup.limit[i] = pp - 1;
24950 pp <<= 1;
24951 t += temp[i];
24952 hufGroup.base[i + 1] = pp - t;
24953 }
24954 hufGroup.limit[maxLen + 1] = Number.MAX_VALUE; /* Sentinal value for reading next sym. */
24955 hufGroup.limit[maxLen] = pp + temp[maxLen] - 1;
24956 hufGroup.base[minLen] = 0;
24957 }
24958 /* We've finished reading and digesting the block header. Now read this
24959 block's huffman coded symbols from the file and undo the huffman coding
24960 and run length encoding, saving the result into dbuf[dbufCount++]=uc */
24961
24962 /* Initialize symbol occurrence counters and symbol Move To Front table */
24963 var byteCount = new Uint32Array(256);
24964 for (i = 0; i < 256; i++)
24965 mtfSymbol[i] = i;
24966 /* Loop through compressed symbols. */
24967 var runPos = 0, dbufCount = 0, selector = 0, uc;
24968 var dbuf = this.dbuf = new Uint32Array(this.dbufSize);
24969 symCount = 0;
24970 for (;;) {
24971 /* Determine which huffman coding group to use. */
24972 if (!(symCount--)) {
24973 symCount = GROUP_SIZE - 1;
24974 if (selector >= nSelectors) { _throw(Err.DATA_ERROR); }
24975 hufGroup = groups[selectors[selector++]];
24976 }
24977 /* Read next huffman-coded symbol. */
24978 i = hufGroup.minLen;
24979 j = reader.read(i);
24980 for (;;i++) {
24981 if (i > hufGroup.maxLen) { _throw(Err.DATA_ERROR); }
24982 if (j <= hufGroup.limit[i])
24983 break;
24984 j = (j << 1) | reader.read(1);
24985 }
24986 /* Huffman decode value to get nextSym (with bounds checking) */
24987 j -= hufGroup.base[i];
24988 if (j < 0 || j >= MAX_SYMBOLS) { _throw(Err.DATA_ERROR); }
24989 var nextSym = hufGroup.permute[j];
24990 /* We have now decoded the symbol, which indicates either a new literal
24991 byte, or a repeated run of the most recent literal byte. First,
24992 check if nextSym indicates a repeated run, and if so loop collecting
24993 how many times to repeat the last literal. */
24994 if (nextSym === SYMBOL_RUNA || nextSym === SYMBOL_RUNB) {
24995 /* If this is the start of a new run, zero out counter */
24996 if (!runPos){
24997 runPos = 1;
24998 t = 0;
24999 }
25000 /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
25001 each bit position, add 1 or 2 instead. For example,
25002 1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
25003 You can make any bit pattern that way using 1 less symbol than
25004 the basic or 0/1 method (except all bits 0, which would use no
25005 symbols, but a run of length 0 doesn't mean anything in this
25006 context). Thus space is saved. */
25007 if (nextSym === SYMBOL_RUNA)
25008 t += runPos;
25009 else
25010 t += 2 * runPos;
25011 runPos <<= 1;
25012 continue;
25013 }
25014 /* When we hit the first non-run symbol after a run, we now know
25015 how many times to repeat the last literal, so append that many
25016 copies to our buffer of decoded symbols (dbuf) now. (The last
25017 literal used is the one at the head of the mtfSymbol array.) */
25018 if (runPos){
25019 runPos = 0;
25020 if (dbufCount + t > this.dbufSize) { _throw(Err.DATA_ERROR); }
25021 uc = symToByte[mtfSymbol[0]];
25022 byteCount[uc] += t;
25023 while (t--)
25024 dbuf[dbufCount++] = uc;
25025 }
25026 /* Is this the terminating symbol? */
25027 if (nextSym > symTotal)
25028 break;
25029 /* At this point, nextSym indicates a new literal character. Subtract
25030 one to get the position in the MTF array at which this literal is
25031 currently to be found. (Note that the result can't be -1 or 0,
25032 because 0 and 1 are RUNA and RUNB. But another instance of the
25033 first symbol in the mtf array, position 0, would have been handled
25034 as part of a run above. Therefore 1 unused mtf position minus
25035 2 non-literal nextSym values equals -1.) */
25036 if (dbufCount >= this.dbufSize) { _throw(Err.DATA_ERROR); }
25037 i = nextSym - 1;
25038 uc = mtf(mtfSymbol, i);
25039 uc = symToByte[uc];
25040 /* We have our literal byte. Save it into dbuf. */
25041 byteCount[uc]++;
25042 dbuf[dbufCount++] = uc;
25043 }
25044 /* At this point, we've read all the huffman-coded symbols (and repeated
25045 runs) for this block from the input stream, and decoded them into the
25046 intermediate buffer. There are dbufCount many decoded bytes in dbuf[].
25047 Now undo the Burrows-Wheeler transform on dbuf.
25048 See http://dogma.net/markn/articles/bwt/bwt.htm
25049 */
25050 if (origPointer < 0 || origPointer >= dbufCount) { _throw(Err.DATA_ERROR); }
25051 /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
25052 j = 0;
25053 for (i = 0; i < 256; i++) {
25054 k = j + byteCount[i];
25055 byteCount[i] = j;
25056 j = k;
25057 }
25058 /* Figure out what order dbuf would be in if we sorted it. */
25059 for (i = 0; i < dbufCount; i++) {
25060 uc = dbuf[i] & 0xff;
25061 dbuf[byteCount[uc]] |= (i << 8);
25062 byteCount[uc]++;
25063 }
25064 /* Decode first byte by hand to initialize "previous" byte. Note that it
25065 doesn't get output, and if the first three characters are identical
25066 it doesn't qualify as a run (hence writeRunCountdown=5). */
25067 var pos = 0, current = 0, run = 0;
25068 if (dbufCount) {
25069 pos = dbuf[origPointer];
25070 current = (pos & 0xff);
25071 pos >>= 8;
25072 run = -1;
25073 }
25074 this.writePos = pos;
25075 this.writeCurrent = current;
25076 this.writeCount = dbufCount;
25077 this.writeRun = run;
25078
25079 return true; /* more blocks to come */
25080};
25081/* Undo burrows-wheeler transform on intermediate buffer to produce output.
25082 If start_bunzip was initialized with out_fd=-1, then up to len bytes of
25083 data are written to outbuf. Return value is number of bytes written or
25084 error (all errors are negative numbers). If out_fd!=-1, outbuf and len
25085 are ignored, data is written to out_fd and return is RETVAL_OK or error.
25086*/
25087Bunzip.prototype._read_bunzip = function(outputBuffer, len) {
25088 var copies, previous, outbyte;
25089 /* james@jamestaylor.org: writeCount goes to -1 when the buffer is fully
25090 decoded, which results in this returning RETVAL_LAST_BLOCK, also
25091 equal to -1... Confusing, I'm returning 0 here to indicate no
25092 bytes written into the buffer */
25093 if (this.writeCount < 0) { return 0; }
25094 var dbuf = this.dbuf, pos = this.writePos, current = this.writeCurrent;
25095 var dbufCount = this.writeCount; this.outputsize;
25096 var run = this.writeRun;
25097
25098 while (dbufCount) {
25099 dbufCount--;
25100 previous = current;
25101 pos = dbuf[pos];
25102 current = pos & 0xff;
25103 pos >>= 8;
25104 if (run++ === 3){
25105 copies = current;
25106 outbyte = previous;
25107 current = -1;
25108 } else {
25109 copies = 1;
25110 outbyte = current;
25111 }
25112 this.blockCRC.updateCRCRun(outbyte, copies);
25113 while (copies--) {
25114 this.outputStream.writeByte(outbyte);
25115 this.nextoutput++;
25116 }
25117 if (current != previous)
25118 run = 0;
25119 }
25120 this.writeCount = dbufCount;
25121 // check CRC
25122 if (this.blockCRC.getCRC() !== this.targetBlockCRC) {
25123 _throw(Err.DATA_ERROR, "Bad block CRC "+
25124 "(got "+this.blockCRC.getCRC().toString(16)+
25125 " expected "+this.targetBlockCRC.toString(16)+")");
25126 }
25127 return this.nextoutput;
25128};
25129
25130var coerceInputStream = function(input) {
25131 if ('readByte' in input) { return input; }
25132 var inputStream = new stream$1();
25133 inputStream.pos = 0;
25134 inputStream.readByte = function() { return input[this.pos++]; };
25135 inputStream.seek = function(pos) { this.pos = pos; };
25136 inputStream.eof = function() { return this.pos >= input.length; };
25137 return inputStream;
25138};
25139var coerceOutputStream = function(output) {
25140 var outputStream = new stream$1();
25141 var resizeOk = true;
25142 if (output) {
25143 if (typeof(output)==='number') {
25144 outputStream.buffer = new Uint8Array(output);
25145 resizeOk = false;
25146 } else if ('writeByte' in output) {
25147 return output;
25148 } else {
25149 outputStream.buffer = output;
25150 resizeOk = false;
25151 }
25152 } else {
25153 outputStream.buffer = new Uint8Array(16384);
25154 }
25155 outputStream.pos = 0;
25156 outputStream.writeByte = function(_byte) {
25157 if (resizeOk && this.pos >= this.buffer.length) {
25158 var newBuffer = new Uint8Array(this.buffer.length*2);
25159 newBuffer.set(this.buffer);
25160 this.buffer = newBuffer;
25161 }
25162 this.buffer[this.pos++] = _byte;
25163 };
25164 outputStream.getBuffer = function() {
25165 // trim buffer
25166 if (this.pos !== this.buffer.length) {
25167 if (!resizeOk)
25168 throw new TypeError('outputsize does not match decoded input');
25169 var newBuffer = new Uint8Array(this.pos);
25170 newBuffer.set(this.buffer.subarray(0, this.pos));
25171 this.buffer = newBuffer;
25172 }
25173 return this.buffer;
25174 };
25175 outputStream._coerced = true;
25176 return outputStream;
25177};
25178
25179/* Static helper functions */
25180// 'input' can be a stream or a buffer
25181// 'output' can be a stream or a buffer or a number (buffer size)
25182const decode$2 = function(input, output, multistream) {
25183 // make a stream from a buffer, if necessary
25184 var inputStream = coerceInputStream(input);
25185 var outputStream = coerceOutputStream(output);
25186
25187 var bz = new Bunzip(inputStream, outputStream);
25188 while (true) {
25189 if ('eof' in inputStream && inputStream.eof()) break;
25190 if (bz._init_block()) {
25191 bz._read_bunzip();
25192 } else {
25193 var targetStreamCRC = bz.reader.read(32) >>> 0; // (convert to unsigned)
25194 if (targetStreamCRC !== bz.streamCRC) {
25195 _throw(Err.DATA_ERROR, "Bad stream CRC "+
25196 "(got "+bz.streamCRC.toString(16)+
25197 " expected "+targetStreamCRC.toString(16)+")");
25198 }
25199 if (multistream &&
25200 'eof' in inputStream &&
25201 !inputStream.eof()) {
25202 // note that start_bunzip will also resync the bit reader to next byte
25203 bz._start_bunzip(inputStream, outputStream);
25204 } else break;
25205 }
25206 }
25207 if ('getBuffer' in outputStream)
25208 return outputStream.getBuffer();
25209};
25210const decodeBlock = function(input, pos, output) {
25211 // make a stream from a buffer, if necessary
25212 var inputStream = coerceInputStream(input);
25213 var outputStream = coerceOutputStream(output);
25214 var bz = new Bunzip(inputStream, outputStream);
25215 bz.reader.seek(pos);
25216 /* Fill the decode buffer for the block */
25217 var moreBlocks = bz._get_next_block();
25218 if (moreBlocks) {
25219 /* Init the CRC for writing */
25220 bz.blockCRC = new crc32$1();
25221
25222 /* Zero this so the current byte from before the seek is not written */
25223 bz.writeCopies = 0;
25224
25225 /* Decompress the block and write to stdout */
25226 bz._read_bunzip();
25227 // XXX keep writing?
25228 }
25229 if ('getBuffer' in outputStream)
25230 return outputStream.getBuffer();
25231};
25232/* Reads bzip2 file from stream or buffer `input`, and invoke
25233 * `callback(position, size)` once for each bzip2 block,
25234 * where position gives the starting position (in *bits*)
25235 * and size gives uncompressed size of the block (in *bytes*). */
25236const table = function(input, callback, multistream) {
25237 // make a stream from a buffer, if necessary
25238 var inputStream = new stream$1();
25239 inputStream.delegate = coerceInputStream(input);
25240 inputStream.pos = 0;
25241 inputStream.readByte = function() {
25242 this.pos++;
25243 return this.delegate.readByte();
25244 };
25245 if (inputStream.delegate.eof) {
25246 inputStream.eof = inputStream.delegate.eof.bind(inputStream.delegate);
25247 }
25248 var outputStream = new stream$1();
25249 outputStream.pos = 0;
25250 outputStream.writeByte = function() { this.pos++; };
25251
25252 var bz = new Bunzip(inputStream, outputStream);
25253 var blockSize = bz.dbufSize;
25254 while (true) {
25255 if ('eof' in inputStream && inputStream.eof()) break;
25256
25257 var position = inputStream.pos*8 + bz.reader.bitOffset;
25258 if (bz.reader.hasByte) { position -= 8; }
25259
25260 if (bz._init_block()) {
25261 var start = outputStream.pos;
25262 bz._read_bunzip();
25263 callback(position, outputStream.pos - start);
25264 } else {
25265 bz.reader.read(32); // (but we ignore the crc)
25266 if (multistream &&
25267 'eof' in inputStream &&
25268 !inputStream.eof()) {
25269 // note that start_bunzip will also resync the bit reader to next byte
25270 bz._start_bunzip(inputStream, outputStream);
25271 console.assert(bz.dbufSize === blockSize,
25272 "shouldn't change block size within multistream file");
25273 } else break;
25274 }
25275 }
25276};
25277
25278var lib = {
25279 Bunzip,
25280 Stream: stream$1,
25281 Err,
25282 decode: decode$2,
25283 decodeBlock,
25284 table
25285};
25286var lib_4 = lib.decode;
25287
25288// GPG4Browsers - An OpenPGP implementation in javascript
25289
25290/**
25291 * Implementation of the Compressed Data Packet (Tag 8)
25292 *
25293 * {@link https://tools.ietf.org/html/rfc4880#section-5.6|RFC4880 5.6}:
25294 * The Compressed Data packet contains compressed data. Typically,
25295 * this packet is found as the contents of an encrypted packet, or following
25296 * a Signature or One-Pass Signature packet, and contains a literal data packet.
25297 */
25298class CompressedDataPacket {
25299 /**
25300 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25301 */
25302 constructor(config = defaultConfig) {
25303 /**
25304 * Packet type
25305 * @type {module:enums.packet}
25306 */
25307 this.tag = enums.packet.compressedData;
25308 /**
25309 * List of packets
25310 * @type {PacketList}
25311 */
25312 this.packets = null;
25313 /**
25314 * Compression algorithm
25315 * @type {compression}
25316 */
25317 this.algorithm = enums.read(enums.compression, config.compression);
25318
25319 /**
25320 * Compressed packet data
25321 * @type {Uint8Array | ReadableStream<Uint8Array>}
25322 */
25323 this.compressed = null;
25324
25325 /**
25326 * zip/zlib compression level, between 1 and 9
25327 */
25328 this.deflateLevel = config.deflateLevel;
25329 }
25330
25331 /**
25332 * Parsing function for the packet.
25333 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - Payload of a tag 8 packet
25334 */
25335 async read(bytes, config, streaming) {
25336 await stream.parse(bytes, async reader => {
25337
25338 // One octet that gives the algorithm used to compress the packet.
25339 this.algorithm = enums.read(enums.compression, await reader.readByte());
25340
25341 // Compressed data, which makes up the remainder of the packet.
25342 this.compressed = reader.remainder();
25343
25344 await this.decompress(streaming);
25345 });
25346 }
25347
25348
25349 /**
25350 * Return the compressed packet.
25351 * @returns {Uint8Array | ReadableStream<Uint8Array>} Binary compressed packet.
25352 */
25353 write() {
25354 if (this.compressed === null) {
25355 this.compress();
25356 }
25357
25358 return util.concat([new Uint8Array([enums.write(enums.compression, this.algorithm)]), this.compressed]);
25359 }
25360
25361
25362 /**
25363 * Decompression method for decompressing the compressed data
25364 * read by read_packet
25365 */
25366 async decompress(streaming) {
25367
25368 if (!decompress_fns[this.algorithm]) {
25369 throw new Error(this.algorithm + ' decompression not supported');
25370 }
25371
25372 await this.packets.read(decompress_fns[this.algorithm](this.compressed), {
25373 LiteralDataPacket,
25374 OnePassSignaturePacket,
25375 SignaturePacket
25376 }, streaming);
25377 }
25378
25379 /**
25380 * Compress the packet data (member decompressedData)
25381 */
25382 compress() {
25383 if (!compress_fns[this.algorithm]) {
25384 throw new Error(this.algorithm + ' compression not supported');
25385 }
25386
25387 this.compressed = compress_fns[this.algorithm](this.packets.write(), this.deflateLevel);
25388 }
25389}
25390
25391//////////////////////////
25392// //
25393// Helper functions //
25394// //
25395//////////////////////////
25396
25397
25398const nodeZlib = util.getNodeZlib();
25399
25400function uncompressed(data) {
25401 return data;
25402}
25403
25404function node_zlib(func, options = {}) {
25405 return function (data) {
25406 return stream.nodeToWeb(stream.webToNode(data).pipe(func(options)));
25407 };
25408}
25409
25410function pako_zlib(constructor, options = {}) {
25411 return function(data) {
25412 const obj = new constructor(options);
25413 return stream.transform(data, value => {
25414 if (value.length) {
25415 obj.push(value, Z_SYNC_FLUSH);
25416 return obj.result;
25417 }
25418 }, () => {
25419 if (constructor === Deflate) {
25420 obj.push([], Z_FINISH);
25421 return obj.result;
25422 }
25423 });
25424 };
25425}
25426
25427function bzip2(func) {
25428 return function(data) {
25429 return stream.fromAsync(async () => func(await stream.readToEnd(data)));
25430 };
25431}
25432
25433const compress_fns = nodeZlib ? {
25434 zip: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.createDeflateRaw, { level })(compressed),
25435 zlib: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.createDeflate, { level })(compressed)
25436} : {
25437 zip: /*#__PURE__*/ (compressed, level) => pako_zlib(Deflate, { raw: true, level })(compressed),
25438 zlib: /*#__PURE__*/ (compressed, level) => pako_zlib(Deflate, { level })(compressed)
25439};
25440
25441const decompress_fns = nodeZlib ? {
25442 uncompressed: uncompressed,
25443 zip: /*#__PURE__*/ node_zlib(nodeZlib.createInflateRaw),
25444 zlib: /*#__PURE__*/ node_zlib(nodeZlib.createInflate),
25445 bzip2: /*#__PURE__*/ bzip2(lib_4)
25446} : {
25447 uncompressed: uncompressed,
25448 zip: /*#__PURE__*/ pako_zlib(Inflate, { raw: true }),
25449 zlib: /*#__PURE__*/ pako_zlib(Inflate),
25450 bzip2: /*#__PURE__*/ bzip2(lib_4)
25451};
25452
25453// GPG4Browsers - An OpenPGP implementation in javascript
25454
25455const VERSION = 1; // A one-octet version number of the data packet.
25456
25457/**
25458 * Implementation of the Sym. Encrypted Integrity Protected Data Packet (Tag 18)
25459 *
25460 * {@link https://tools.ietf.org/html/rfc4880#section-5.13|RFC4880 5.13}:
25461 * The Symmetrically Encrypted Integrity Protected Data packet is
25462 * a variant of the Symmetrically Encrypted Data packet. It is a new feature
25463 * created for OpenPGP that addresses the problem of detecting a modification to
25464 * encrypted data. It is used in combination with a Modification Detection Code
25465 * packet.
25466 */
25467class SymEncryptedIntegrityProtectedDataPacket {
25468 constructor() {
25469 this.tag = enums.packet.symEncryptedIntegrityProtectedData;
25470 this.version = VERSION;
25471 /** The encrypted payload. */
25472 this.encrypted = null; // string
25473 /**
25474 * If after decrypting the packet this is set to true,
25475 * a modification has been detected and thus the contents
25476 * should be discarded.
25477 * @type {Boolean}
25478 */
25479 this.modification = false;
25480 this.packets = null;
25481 }
25482
25483 async read(bytes) {
25484 await stream.parse(bytes, async reader => {
25485
25486 // - A one-octet version number. The only currently defined value is 1.
25487 if (await reader.readByte() !== VERSION) {
25488 throw new Error('Invalid packet version.');
25489 }
25490
25491 // - Encrypted data, the output of the selected symmetric-key cipher
25492 // operating in Cipher Feedback mode with shift amount equal to the
25493 // block size of the cipher (CFB-n where n is the block size).
25494 this.encrypted = reader.remainder();
25495 });
25496 }
25497
25498 write() {
25499 return util.concat([new Uint8Array([VERSION]), this.encrypted]);
25500 }
25501
25502 /**
25503 * Encrypt the payload in the packet.
25504 * @param {String} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used e.g. 'aes128'
25505 * @param {Uint8Array} key - The key of cipher blocksize length to be used
25506 * @param {Boolean} streaming - Whether to set this.encrypted to a stream
25507 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25508 * @returns {Boolean}
25509 * @async
25510 */
25511 async encrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
25512 let bytes = this.packets.write();
25513 if (!streaming) bytes = await stream.readToEnd(bytes);
25514 const prefix = await mod.getPrefixRandom(sessionKeyAlgorithm);
25515 const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
25516
25517 const tohash = util.concat([prefix, bytes, mdc]);
25518 const hash = await mod.hash.sha1(stream.passiveClone(tohash));
25519 const plaintext = util.concat([tohash, hash]);
25520
25521 this.encrypted = await mod.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(mod.cipher[sessionKeyAlgorithm].blockSize), config);
25522 return true;
25523 }
25524
25525 /**
25526 * Decrypts the encrypted data contained in the packet.
25527 * @param {String} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used e.g. 'aes128'
25528 * @param {Uint8Array} key - The key of cipher blocksize length to be used
25529 * @param {Boolean} streaming - Whether to read this.encrypted as a stream
25530 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25531 * @returns {Boolean}
25532 * @async
25533 */
25534 async decrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
25535 let encrypted = stream.clone(this.encrypted);
25536 if (!streaming) encrypted = await stream.readToEnd(encrypted);
25537 const decrypted = await mod.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(mod.cipher[sessionKeyAlgorithm].blockSize));
25538
25539 // there must be a modification detection code packet as the
25540 // last packet and everything gets hashed except the hash itself
25541 const realHash = stream.slice(stream.passiveClone(decrypted), -20);
25542 const tohash = stream.slice(decrypted, 0, -20);
25543 const verifyHash = Promise.all([
25544 stream.readToEnd(await mod.hash.sha1(stream.passiveClone(tohash))),
25545 stream.readToEnd(realHash)
25546 ]).then(([hash, mdc]) => {
25547 if (!util.equalsUint8Array(hash, mdc)) {
25548 throw new Error('Modification detected.');
25549 }
25550 return new Uint8Array();
25551 });
25552 const bytes = stream.slice(tohash, mod.cipher[sessionKeyAlgorithm].blockSize + 2); // Remove random prefix
25553 let packetbytes = stream.slice(bytes, 0, -2); // Remove MDC packet
25554 packetbytes = stream.concat([packetbytes, stream.fromAsync(() => verifyHash)]);
25555 if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
25556 packetbytes = await stream.readToEnd(packetbytes);
25557 }
25558 await this.packets.read(packetbytes, {
25559 LiteralDataPacket,
25560 CompressedDataPacket,
25561 OnePassSignaturePacket,
25562 SignaturePacket
25563 }, streaming);
25564 return true;
25565 }
25566}
25567
25568// OpenPGP.js - An OpenPGP implementation in javascript
25569
25570const VERSION$1 = 1; // A one-octet version number of the data packet.
25571
25572/**
25573 * Implementation of the Symmetrically Encrypted Authenticated Encryption with
25574 * Additional Data (AEAD) Protected Data Packet
25575 *
25576 * {@link https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1}:
25577 * AEAD Protected Data Packet
25578 */
25579class AEADEncryptedDataPacket {
25580 constructor() {
25581 this.tag = enums.packet.AEADEncryptedData;
25582 this.version = VERSION$1;
25583 this.cipherAlgo = null;
25584 this.aeadAlgorithm = 'eax';
25585 this.aeadAlgo = null;
25586 this.chunkSizeByte = null;
25587 this.iv = null;
25588 this.encrypted = null;
25589 this.packets = null;
25590 }
25591
25592 /**
25593 * Parse an encrypted payload of bytes in the order: version, IV, ciphertext (see specification)
25594 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes
25595 */
25596 async read(bytes) {
25597 await stream.parse(bytes, async reader => {
25598 if (await reader.readByte() !== VERSION$1) { // The only currently defined value is 1.
25599 throw new Error('Invalid packet version.');
25600 }
25601 this.cipherAlgo = await reader.readByte();
25602 this.aeadAlgo = await reader.readByte();
25603 this.chunkSizeByte = await reader.readByte();
25604 const mode = mod[enums.read(enums.aead, this.aeadAlgo)];
25605 this.iv = await reader.readBytes(mode.ivLength);
25606 this.encrypted = reader.remainder();
25607 });
25608 }
25609
25610 /**
25611 * Write the encrypted payload of bytes in the order: version, IV, ciphertext (see specification)
25612 * @returns {Uint8Array | ReadableStream<Uint8Array>} The encrypted payload.
25613 */
25614 write() {
25615 return util.concat([new Uint8Array([this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte]), this.iv, this.encrypted]);
25616 }
25617
25618 /**
25619 * Decrypt the encrypted payload.
25620 * @param {String} sessionKeyAlgorithm - The session key's cipher algorithm e.g. 'aes128'
25621 * @param {Uint8Array} key - The session key used to encrypt the payload
25622 * @param {Boolean} streaming - Whether the top-level function will return a stream
25623 * @throws {Error} if decryption was not successful
25624 * @async
25625 */
25626 async decrypt(sessionKeyAlgorithm, key, streaming) {
25627 await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted), streaming), {
25628 LiteralDataPacket,
25629 CompressedDataPacket,
25630 OnePassSignaturePacket,
25631 SignaturePacket
25632 }, streaming);
25633 }
25634
25635 /**
25636 * Encrypt the packet list payload.
25637 * @param {String} sessionKeyAlgorithm - The session key's cipher algorithm e.g. 'aes128'
25638 * @param {Uint8Array} key - The session key used to encrypt the payload
25639 * @param {Boolean} streaming - Whether the top-level function will return a stream
25640 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25641 * @throws {Error} if encryption was not successful
25642 * @async
25643 */
25644 async encrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
25645 this.cipherAlgo = enums.write(enums.symmetric, sessionKeyAlgorithm);
25646 this.aeadAlgo = enums.write(enums.aead, this.aeadAlgorithm);
25647 const mode = mod[enums.read(enums.aead, this.aeadAlgo)];
25648 this.iv = await mod.random.getRandomBytes(mode.ivLength); // generate new random IV
25649 this.chunkSizeByte = config.aeadChunkSizeByte;
25650 const data = this.packets.write();
25651 this.encrypted = await this.crypt('encrypt', key, data, streaming);
25652 }
25653
25654 /**
25655 * En/decrypt the payload.
25656 * @param {encrypt|decrypt} fn - Whether to encrypt or decrypt
25657 * @param {Uint8Array} key - The session key used to en/decrypt the payload
25658 * @param {Uint8Array | ReadableStream<Uint8Array>} data - The data to en/decrypt
25659 * @param {Boolean} streaming - Whether the top-level function will return a stream
25660 * @returns {Uint8Array | ReadableStream<Uint8Array>}
25661 * @async
25662 */
25663 async crypt(fn, key, data, streaming) {
25664 const cipher = enums.read(enums.symmetric, this.cipherAlgo);
25665 const mode = mod[enums.read(enums.aead, this.aeadAlgo)];
25666 const modeInstance = await mode(cipher, key);
25667 const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0;
25668 const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0;
25669 const chunkSize = 2 ** (this.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6))
25670 const adataBuffer = new ArrayBuffer(21);
25671 const adataArray = new Uint8Array(adataBuffer, 0, 13);
25672 const adataTagArray = new Uint8Array(adataBuffer);
25673 const adataView = new DataView(adataBuffer);
25674 const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8);
25675 adataArray.set([0xC0 | this.tag, this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte], 0);
25676 let chunkIndex = 0;
25677 let latestPromise = Promise.resolve();
25678 let cryptedBytes = 0;
25679 let queuedBytes = 0;
25680 const iv = this.iv;
25681 return stream.transformPair(data, async (readable, writable) => {
25682 const reader = stream.getReader(readable);
25683 const buffer = new stream.TransformStream({}, {
25684 highWaterMark: streaming ? util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6) : Infinity,
25685 size: array => array.length
25686 });
25687 stream.pipe(buffer.readable, writable);
25688 const writer = stream.getWriter(buffer.writable);
25689 try {
25690 while (true) {
25691 let chunk = await reader.readBytes(chunkSize + tagLengthIfDecrypting) || new Uint8Array();
25692 const finalChunk = chunk.subarray(chunk.length - tagLengthIfDecrypting);
25693 chunk = chunk.subarray(0, chunk.length - tagLengthIfDecrypting);
25694 let cryptedPromise;
25695 let done;
25696 if (!chunkIndex || chunk.length) {
25697 reader.unshift(finalChunk);
25698 cryptedPromise = modeInstance[fn](chunk, mode.getNonce(iv, chunkIndexArray), adataArray);
25699 queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting;
25700 } else {
25701 // After the last chunk, we either encrypt a final, empty
25702 // data chunk to get the final authentication tag or
25703 // validate that final authentication tag.
25704 adataView.setInt32(13 + 4, cryptedBytes); // Should be setInt64(13, ...)
25705 cryptedPromise = modeInstance[fn](finalChunk, mode.getNonce(iv, chunkIndexArray), adataTagArray);
25706 queuedBytes += tagLengthIfEncrypting;
25707 done = true;
25708 }
25709 cryptedBytes += chunk.length - tagLengthIfDecrypting;
25710 // eslint-disable-next-line no-loop-func
25711 latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => {
25712 await writer.ready;
25713 await writer.write(crypted);
25714 queuedBytes -= crypted.length;
25715 }).catch(err => writer.abort(err));
25716 if (done || queuedBytes > writer.desiredSize) {
25717 await latestPromise; // Respect backpressure
25718 }
25719 if (!done) {
25720 adataView.setInt32(5 + 4, ++chunkIndex); // Should be setInt64(5, ...)
25721 } else {
25722 await writer.close();
25723 break;
25724 }
25725 }
25726 } catch (e) {
25727 await writer.abort(e);
25728 }
25729 });
25730 }
25731}
25732
25733// GPG4Browsers - An OpenPGP implementation in javascript
25734
25735/**
25736 * Public-Key Encrypted Session Key Packets (Tag 1)
25737 *
25738 * {@link https://tools.ietf.org/html/rfc4880#section-5.1|RFC4880 5.1}:
25739 * A Public-Key Encrypted Session Key packet holds the session key
25740 * used to encrypt a message. Zero or more Public-Key Encrypted Session Key
25741 * packets and/or Symmetric-Key Encrypted Session Key packets may precede a
25742 * Symmetrically Encrypted Data Packet, which holds an encrypted message. The
25743 * message is encrypted with the session key, and the session key is itself
25744 * encrypted and stored in the Encrypted Session Key packet(s). The
25745 * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted
25746 * Session Key packet for each OpenPGP key to which the message is encrypted.
25747 * The recipient of the message finds a session key that is encrypted to their
25748 * public key, decrypts the session key, and then uses the session key to
25749 * decrypt the message.
25750 */
25751class PublicKeyEncryptedSessionKeyPacket {
25752 constructor() {
25753 this.tag = enums.packet.publicKeyEncryptedSessionKey;
25754 this.version = 3;
25755
25756 this.publicKeyId = new Keyid();
25757 this.publicKeyAlgorithm = null;
25758
25759 this.sessionKey = null;
25760 this.sessionKeyAlgorithm = null;
25761
25762 /** @type {Object} */
25763 this.encrypted = {};
25764 }
25765
25766 /**
25767 * Parsing function for a publickey encrypted session key packet (tag 1).
25768 *
25769 * @param {Uint8Array} bytes - Payload of a tag 1 packet
25770 */
25771 read(bytes) {
25772 this.version = bytes[0];
25773 this.publicKeyId.read(bytes.subarray(1, bytes.length));
25774 this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9]);
25775
25776 const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
25777 this.encrypted = mod.parseEncSessionKeyParams(algo, bytes.subarray(10));
25778 }
25779
25780 /**
25781 * Create a binary representation of a tag 1 packet
25782 *
25783 * @returns {Uint8Array} The Uint8Array representation.
25784 */
25785 write() {
25786 const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
25787
25788 const arr = [
25789 new Uint8Array([this.version]),
25790 this.publicKeyId.write(),
25791 new Uint8Array([enums.write(enums.publicKey, this.publicKeyAlgorithm)]),
25792 mod.serializeParams(algo, this.encrypted)
25793 ];
25794
25795 return util.concatUint8Array(arr);
25796 }
25797
25798 /**
25799 * Encrypt session key packet
25800 * @param {PublicKeyPacket} key - Public key
25801 * @returns {Boolean}
25802 * @async
25803 */
25804 async encrypt(key) {
25805 const data = util.concatUint8Array([
25806 new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]),
25807 this.sessionKey,
25808 util.writeChecksum(this.sessionKey)
25809 ]);
25810 const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
25811 this.encrypted = await mod.publicKeyEncrypt(
25812 algo, key.publicParams, data, key.getFingerprintBytes());
25813 return true;
25814 }
25815
25816 /**
25817 * Decrypts the session key (only for public key encrypted session key
25818 * packets (tag 1)
25819 *
25820 * @param {SecretKeyPacket} key
25821 * Private key with secret params unlocked
25822 * @returns {Boolean}
25823 * @async
25824 */
25825 async decrypt(key) {
25826 const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
25827 const keyAlgo = enums.write(enums.publicKey, key.algorithm);
25828 // check that session key algo matches the secret key algo
25829 if (algo !== keyAlgo) {
25830 throw new Error('Decryption error');
25831 }
25832 const decoded = await mod.publicKeyDecrypt(algo, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes());
25833 const checksum = decoded.subarray(decoded.length - 2);
25834 const sessionKey = decoded.subarray(1, decoded.length - 2);
25835 if (!util.equalsUint8Array(checksum, util.writeChecksum(sessionKey))) {
25836 throw new Error('Decryption error');
25837 } else {
25838 this.sessionKey = sessionKey;
25839 this.sessionKeyAlgorithm = enums.read(enums.symmetric, decoded[0]);
25840 }
25841 return true;
25842 }
25843}
25844
25845// GPG4Browsers - An OpenPGP implementation in javascript
25846
25847class S2K {
25848 /**
25849 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25850 */
25851 constructor(config = defaultConfig) {
25852 /** @type {module:enums.hash} */
25853 this.algorithm = 'sha256';
25854 /** @type {module:enums.s2k} */
25855 this.type = 'iterated';
25856 /** @type {Integer} */
25857 this.c = config.s2kIterationCountByte;
25858 /** Eight bytes of salt in a binary string.
25859 * @type {String}
25860 */
25861 this.salt = null;
25862 }
25863
25864 get_count() {
25865 // Exponent bias, defined in RFC4880
25866 const expbias = 6;
25867
25868 return (16 + (this.c & 15)) << ((this.c >> 4) + expbias);
25869 }
25870
25871 /**
25872 * Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}).
25873 * @param {String} bytes - Payload of string-to-key specifier
25874 * @returns {Integer} Actual length of the object.
25875 */
25876 read(bytes) {
25877 let i = 0;
25878 this.type = enums.read(enums.s2k, bytes[i++]);
25879 this.algorithm = bytes[i++];
25880 if (this.type !== 'gnu') {
25881 this.algorithm = enums.read(enums.hash, this.algorithm);
25882 }
25883
25884 switch (this.type) {
25885 case 'simple':
25886 break;
25887
25888 case 'salted':
25889 this.salt = bytes.subarray(i, i + 8);
25890 i += 8;
25891 break;
25892
25893 case 'iterated':
25894 this.salt = bytes.subarray(i, i + 8);
25895 i += 8;
25896
25897 // Octet 10: count, a one-octet, coded value
25898 this.c = bytes[i++];
25899 break;
25900
25901 case 'gnu':
25902 if (util.uint8ArrayToStr(bytes.subarray(i, i + 3)) === "GNU") {
25903 i += 3; // GNU
25904 const gnuExtType = 1000 + bytes[i++];
25905 if (gnuExtType === 1001) {
25906 this.type = 'gnu-dummy';
25907 // GnuPG extension mode 1001 -- don't write secret key at all
25908 } else {
25909 throw new Error("Unknown s2k gnu protection mode.");
25910 }
25911 } else {
25912 throw new Error("Unknown s2k type.");
25913 }
25914 break;
25915
25916 default:
25917 throw new Error("Unknown s2k type.");
25918 }
25919
25920 return i;
25921 }
25922
25923 /**
25924 * Serializes s2k information
25925 * @returns {Uint8Array} Binary representation of s2k.
25926 */
25927 write() {
25928 if (this.type === 'gnu-dummy') {
25929 return new Uint8Array([101, 0, ...util.strToUint8Array('GNU'), 1]);
25930 }
25931
25932 const arr = [new Uint8Array([enums.write(enums.s2k, this.type), enums.write(enums.hash, this.algorithm)])];
25933
25934 switch (this.type) {
25935 case 'simple':
25936 break;
25937 case 'salted':
25938 arr.push(this.salt);
25939 break;
25940 case 'iterated':
25941 arr.push(this.salt);
25942 arr.push(new Uint8Array([this.c]));
25943 break;
25944 case 'gnu':
25945 throw new Error("GNU s2k type not supported.");
25946 default:
25947 throw new Error("Unknown s2k type.");
25948 }
25949
25950 return util.concatUint8Array(arr);
25951 }
25952
25953 /**
25954 * Produces a key using the specified passphrase and the defined
25955 * hashAlgorithm
25956 * @param {String} passphrase - Passphrase containing user input
25957 * @returns {Uint8Array} Produced key with a length corresponding to.
25958 * hashAlgorithm hash length
25959 */
25960 async produce_key(passphrase, numBytes) {
25961 passphrase = util.encodeUtf8(passphrase);
25962 const algorithm = enums.write(enums.hash, this.algorithm);
25963
25964 const arr = [];
25965 let rlength = 0;
25966
25967 let prefixlen = 0;
25968 while (rlength < numBytes) {
25969 let toHash;
25970 switch (this.type) {
25971 case 'simple':
25972 toHash = util.concatUint8Array([new Uint8Array(prefixlen), passphrase]);
25973 break;
25974 case 'salted':
25975 toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, passphrase]);
25976 break;
25977 case 'iterated': {
25978 const data = util.concatUint8Array([this.salt, passphrase]);
25979 let datalen = data.length;
25980 const count = Math.max(this.get_count(), datalen);
25981 toHash = new Uint8Array(prefixlen + count);
25982 toHash.set(data, prefixlen);
25983 for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) {
25984 toHash.copyWithin(pos, prefixlen, pos);
25985 }
25986 break;
25987 }
25988 case 'gnu':
25989 throw new Error("GNU s2k type not supported.");
25990 default:
25991 throw new Error("Unknown s2k type.");
25992 }
25993 const result = await mod.hash.digest(algorithm, toHash);
25994 arr.push(result);
25995 rlength += result.length;
25996 prefixlen++;
25997 }
25998
25999 return util.concatUint8Array(arr).subarray(0, numBytes);
26000 }
26001}
26002
26003// GPG4Browsers - An OpenPGP implementation in javascript
26004
26005/**
26006 * Symmetric-Key Encrypted Session Key Packets (Tag 3)
26007 *
26008 * {@link https://tools.ietf.org/html/rfc4880#section-5.3|RFC4880 5.3}:
26009 * The Symmetric-Key Encrypted Session Key packet holds the
26010 * symmetric-key encryption of a session key used to encrypt a message.
26011 * Zero or more Public-Key Encrypted Session Key packets and/or
26012 * Symmetric-Key Encrypted Session Key packets may precede a
26013 * Symmetrically Encrypted Data packet that holds an encrypted message.
26014 * The message is encrypted with a session key, and the session key is
26015 * itself encrypted and stored in the Encrypted Session Key packet or
26016 * the Symmetric-Key Encrypted Session Key packet.
26017 */
26018class SymEncryptedSessionKeyPacket {
26019 /**
26020 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26021 */
26022 constructor(config = defaultConfig) {
26023 this.tag = enums.packet.symEncryptedSessionKey;
26024 this.version = config.aeadProtect ? 5 : 4;
26025 this.sessionKey = null;
26026 this.sessionKeyEncryptionAlgorithm = null;
26027 this.sessionKeyAlgorithm = 'aes256';
26028 this.aeadAlgorithm = enums.read(enums.aead, config.aeadMode);
26029 this.encrypted = null;
26030 this.s2k = null;
26031 this.iv = null;
26032 }
26033
26034 /**
26035 * Parsing function for a symmetric encrypted session key packet (tag 3).
26036 *
26037 * @param {Uint8Array} bytes - Payload of a tag 3 packet
26038 */
26039 read(bytes) {
26040 let offset = 0;
26041
26042 // A one-octet version number. The only currently defined version is 4.
26043 this.version = bytes[offset++];
26044
26045 // A one-octet number describing the symmetric algorithm used.
26046 const algo = enums.read(enums.symmetric, bytes[offset++]);
26047
26048 if (this.version === 5) {
26049 // A one-octet AEAD algorithm.
26050 this.aeadAlgorithm = enums.read(enums.aead, bytes[offset++]);
26051 }
26052
26053 // A string-to-key (S2K) specifier, length as defined above.
26054 this.s2k = new S2K();
26055 offset += this.s2k.read(bytes.subarray(offset, bytes.length));
26056
26057 if (this.version === 5) {
26058 const mode = mod[this.aeadAlgorithm];
26059
26060 // A starting initialization vector of size specified by the AEAD
26061 // algorithm.
26062 this.iv = bytes.subarray(offset, offset += mode.ivLength);
26063 }
26064
26065 // The encrypted session key itself, which is decrypted with the
26066 // string-to-key object. This is optional in version 4.
26067 if (this.version === 5 || offset < bytes.length) {
26068 this.encrypted = bytes.subarray(offset, bytes.length);
26069 this.sessionKeyEncryptionAlgorithm = algo;
26070 } else {
26071 this.sessionKeyAlgorithm = algo;
26072 }
26073 }
26074
26075 /**
26076 * Create a binary representation of a tag 3 packet
26077 *
26078 * @returns {Uint8Array} The Uint8Array representation.
26079 */
26080 write() {
26081 const algo = this.encrypted === null ?
26082 this.sessionKeyAlgorithm :
26083 this.sessionKeyEncryptionAlgorithm;
26084
26085 let bytes;
26086
26087 if (this.version === 5) {
26088 bytes = util.concatUint8Array([new Uint8Array([this.version, enums.write(enums.symmetric, algo), enums.write(enums.aead, this.aeadAlgorithm)]), this.s2k.write(), this.iv, this.encrypted]);
26089 } else {
26090 bytes = util.concatUint8Array([new Uint8Array([this.version, enums.write(enums.symmetric, algo)]), this.s2k.write()]);
26091
26092 if (this.encrypted !== null) {
26093 bytes = util.concatUint8Array([bytes, this.encrypted]);
26094 }
26095 }
26096
26097 return bytes;
26098 }
26099
26100 /**
26101 * Decrypts the session key
26102 * @param {String} passphrase - The passphrase in string form
26103 * @throws {Error} if decryption was not successful
26104 * @async
26105 */
26106 async decrypt(passphrase) {
26107 const algo = this.sessionKeyEncryptionAlgorithm !== null ?
26108 this.sessionKeyEncryptionAlgorithm :
26109 this.sessionKeyAlgorithm;
26110
26111 const length = mod.cipher[algo].keySize;
26112 const key = await this.s2k.produce_key(passphrase, length);
26113
26114 if (this.version === 5) {
26115 const mode = mod[this.aeadAlgorithm];
26116 const adata = new Uint8Array([0xC0 | this.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]);
26117 const modeInstance = await mode(algo, key);
26118 this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata);
26119 } else if (this.encrypted !== null) {
26120 const decrypted = await mod.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(mod.cipher[algo].blockSize));
26121
26122 this.sessionKeyAlgorithm = enums.read(enums.symmetric, decrypted[0]);
26123 this.sessionKey = decrypted.subarray(1, decrypted.length);
26124 } else {
26125 this.sessionKey = key;
26126 }
26127 }
26128
26129 /**
26130 * Encrypts the session key
26131 * @param {String} passphrase - The passphrase in string form
26132 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26133 * @throws {Error} if encryption was not successful
26134 * @async
26135 */
26136 async encrypt(passphrase, config = defaultConfig) {
26137 const algo = this.sessionKeyEncryptionAlgorithm !== null ?
26138 this.sessionKeyEncryptionAlgorithm :
26139 this.sessionKeyAlgorithm;
26140
26141 this.sessionKeyEncryptionAlgorithm = algo;
26142
26143 this.s2k = new S2K(config);
26144 this.s2k.salt = await mod.random.getRandomBytes(8);
26145
26146 const length = mod.cipher[algo].keySize;
26147 const key = await this.s2k.produce_key(passphrase, length);
26148
26149 if (this.sessionKey === null) {
26150 this.sessionKey = await mod.generateSessionKey(this.sessionKeyAlgorithm);
26151 }
26152
26153 if (this.version === 5) {
26154 const mode = mod[this.aeadAlgorithm];
26155 this.iv = await mod.random.getRandomBytes(mode.ivLength); // generate new random IV
26156 const adata = new Uint8Array([0xC0 | this.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]);
26157 const modeInstance = await mode(algo, key);
26158 this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, adata);
26159 } else {
26160 const algo_enum = new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]);
26161 const private_key = util.concatUint8Array([algo_enum, this.sessionKey]);
26162 this.encrypted = await mod.cfb.encrypt(algo, key, private_key, new Uint8Array(mod.cipher[algo].blockSize), config);
26163 }
26164 }
26165}
26166
26167// GPG4Browsers - An OpenPGP implementation in javascript
26168
26169/**
26170 * Implementation of the Literal Data Packet (Tag 11)
26171 *
26172 * {@link https://tools.ietf.org/html/rfc4880#section-5.9|RFC4880 5.9}:
26173 * A Literal Data packet contains the body of a message; data that is not to be
26174 * further interpreted.
26175 */
26176class LiteralDataPacket {
26177 /**
26178 * @param {Date} date - The creation date of the literal package
26179 */
26180 constructor(date = new Date()) {
26181 this.tag = enums.packet.literalData;
26182 this.format = 'utf8'; // default format for literal data packets
26183 this.date = util.normalizeDate(date);
26184 this.text = null; // textual data representation
26185 this.data = null; // literal data representation
26186 this.filename = '';
26187 }
26188
26189 /**
26190 * Set the packet data to a javascript native string, end of line
26191 * will be normalized to \r\n and by default text is converted to UTF8
26192 * @param {String | ReadableStream<String>} text - Any native javascript string
26193 * @param {utf8|binary|text|mime} [format] - The format of the string of bytes
26194 */
26195 setText(text, format = 'utf8') {
26196 this.format = format;
26197 this.text = text;
26198 this.data = null;
26199 }
26200
26201 /**
26202 * Returns literal data packets as native JavaScript string
26203 * with normalized end of line to \n
26204 * @param {Boolean} [clone] - Whether to return a clone so that getBytes/getText can be called again
26205 * @returns {String | ReadableStream<String>} Literal data as text.
26206 */
26207 getText(clone = false) {
26208 if (this.text === null || util.isStream(this.text)) { // Assume that this.text has been read
26209 this.text = util.decodeUtf8(util.nativeEOL(this.getBytes(clone)));
26210 }
26211 return this.text;
26212 }
26213
26214 /**
26215 * Set the packet data to value represented by the provided string of bytes.
26216 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - The string of bytes
26217 * @param {utf8|binary|text|mime} format - The format of the string of bytes
26218 */
26219 setBytes(bytes, format) {
26220 this.format = format;
26221 this.data = bytes;
26222 this.text = null;
26223 }
26224
26225
26226 /**
26227 * Get the byte sequence representing the literal packet data
26228 * @param {Boolean} [clone] - Whether to return a clone so that getBytes/getText can be called again
26229 * @returns {Uint8Array | ReadableStream<Uint8Array>} A sequence of bytes.
26230 */
26231 getBytes(clone = false) {
26232 if (this.data === null) {
26233 // encode UTF8 and normalize EOL to \r\n
26234 this.data = util.canonicalizeEOL(util.encodeUtf8(this.text));
26235 }
26236 if (clone) {
26237 return stream.passiveClone(this.data);
26238 }
26239 return this.data;
26240 }
26241
26242
26243 /**
26244 * Sets the filename of the literal packet data
26245 * @param {String} filename - Any native javascript string
26246 */
26247 setFilename(filename) {
26248 this.filename = filename;
26249 }
26250
26251
26252 /**
26253 * Get the filename of the literal packet data
26254 * @returns {String} Filename.
26255 */
26256 getFilename() {
26257 return this.filename;
26258 }
26259
26260
26261 /**
26262 * Parsing function for a literal data packet (tag 11).
26263 *
26264 * @param {Uint8Array | ReadableStream<Uint8Array>} input - Payload of a tag 11 packet
26265 * @returns {LiteralDataPacket} Object representation.
26266 */
26267 async read(bytes) {
26268 await stream.parse(bytes, async reader => {
26269 // - A one-octet field that describes how the data is formatted.
26270 const format = enums.read(enums.literal, await reader.readByte());
26271
26272 const filename_len = await reader.readByte();
26273 this.filename = util.decodeUtf8(await reader.readBytes(filename_len));
26274
26275 this.date = util.readDate(await reader.readBytes(4));
26276
26277 const data = reader.remainder();
26278
26279 this.setBytes(data, format);
26280 });
26281 }
26282
26283 /**
26284 * Creates a Uint8Array representation of the packet, excluding the data
26285 *
26286 * @returns {Uint8Array} Uint8Array representation of the packet.
26287 */
26288 writeHeader() {
26289 const filename = util.encodeUtf8(this.filename);
26290 const filename_length = new Uint8Array([filename.length]);
26291
26292 const format = new Uint8Array([enums.write(enums.literal, this.format)]);
26293 const date = util.writeDate(this.date);
26294
26295 return util.concatUint8Array([format, filename_length, filename, date]);
26296 }
26297
26298 /**
26299 * Creates a Uint8Array representation of the packet
26300 *
26301 * @returns {Uint8Array | ReadableStream<Uint8Array>} Uint8Array representation of the packet.
26302 */
26303 write() {
26304 const header = this.writeHeader();
26305 const data = this.getBytes();
26306
26307 return util.concat([header, data]);
26308 }
26309}
26310
26311// GPG4Browsers - An OpenPGP implementation in javascript
26312
26313/**
26314 * Implementation of the Key Material Packet (Tag 5,6,7,14)
26315 *
26316 * {@link https://tools.ietf.org/html/rfc4880#section-5.5|RFC4480 5.5}:
26317 * A key material packet contains all the information about a public or
26318 * private key. There are four variants of this packet type, and two
26319 * major versions.
26320 *
26321 * A Public-Key packet starts a series of packets that forms an OpenPGP
26322 * key (sometimes called an OpenPGP certificate).
26323 */
26324class PublicKeyPacket {
26325 /**
26326 * @param {Date} [date] - Creation date
26327 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26328 */
26329 constructor(date = new Date(), config = defaultConfig) {
26330 /**
26331 * Packet type
26332 * @type {module:enums.packet}
26333 */
26334 this.tag = enums.packet.publicKey;
26335 /**
26336 * Packet version
26337 * @type {Integer}
26338 */
26339 this.version = config.v5Keys ? 5 : 4;
26340 /**
26341 * Key creation date.
26342 * @type {Date}
26343 */
26344 this.created = util.normalizeDate(date);
26345 /**
26346 * Public key algorithm.
26347 * @type {String}
26348 */
26349 this.algorithm = null;
26350 /**
26351 * Algorithm specific public params
26352 * @type {Object}
26353 */
26354 this.publicParams = null;
26355 /**
26356 * Time until expiration in days (V3 only)
26357 * @type {Integer}
26358 */
26359 this.expirationTimeV3 = 0;
26360 /**
26361 * Fingerprint in lowercase hex
26362 * @type {String}
26363 */
26364 this.fingerprint = null;
26365 /**
26366 * Keyid
26367 * @type {module:type/keyid~Keyid}
26368 */
26369 this.keyid = null;
26370 }
26371
26372 /**
26373 * 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}
26374 * called by read_tag&lt;num&gt;
26375 * @param {Uint8Array} bytes - Input array to read the packet from
26376 * @returns {Object} This object with attributes set by the parser.
26377 */
26378 read(bytes) {
26379 let pos = 0;
26380 // A one-octet version number (3, 4 or 5).
26381 this.version = bytes[pos++];
26382
26383 if (this.version === 4 || this.version === 5) {
26384 // - A four-octet number denoting the time that the key was created.
26385 this.created = util.readDate(bytes.subarray(pos, pos + 4));
26386 pos += 4;
26387
26388 // - A one-octet number denoting the public-key algorithm of this key.
26389 this.algorithm = enums.read(enums.publicKey, bytes[pos++]);
26390 const algo = enums.write(enums.publicKey, this.algorithm);
26391
26392 if (this.version === 5) {
26393 // - A four-octet scalar octet count for the following key material.
26394 pos += 4;
26395 }
26396
26397 // - A series of values comprising the key material.
26398 try {
26399 const { read, publicParams } = mod.parsePublicKeyParams(algo, bytes.subarray(pos));
26400 this.publicParams = publicParams;
26401 pos += read;
26402 } catch (err) {
26403 throw new Error('Error reading MPIs');
26404 }
26405
26406 return pos;
26407 }
26408 throw new Error('Version ' + this.version + ' of the key packet is unsupported.');
26409 }
26410
26411 /**
26412 * Creates an OpenPGP public key packet for the given key.
26413 * @returns {Uint8Array} Bytes encoding the public key OpenPGP packet.
26414 */
26415 write() {
26416 const arr = [];
26417 // Version
26418 arr.push(new Uint8Array([this.version]));
26419 arr.push(util.writeDate(this.created));
26420 // A one-octet number denoting the public-key algorithm of this key
26421 const algo = enums.write(enums.publicKey, this.algorithm);
26422 arr.push(new Uint8Array([algo]));
26423
26424 const params = mod.serializeParams(algo, this.publicParams);
26425 if (this.version === 5) {
26426 // A four-octet scalar octet count for the following key material
26427 arr.push(util.writeNumber(params.length, 4));
26428 }
26429 // Algorithm-specific params
26430 arr.push(params);
26431 return util.concatUint8Array(arr);
26432 }
26433
26434 /**
26435 * Write packet in order to be hashed; either for a signature or a fingerprint.
26436 */
26437 writeForHash(version) {
26438 const bytes = this.writePublicKey();
26439
26440 if (version === 5) {
26441 return util.concatUint8Array([new Uint8Array([0x9A]), util.writeNumber(bytes.length, 4), bytes]);
26442 }
26443 return util.concatUint8Array([new Uint8Array([0x99]), util.writeNumber(bytes.length, 2), bytes]);
26444 }
26445
26446 /**
26447 * Check whether secret-key data is available in decrypted form. Returns null for public keys.
26448 * @returns {Boolean|null}
26449 */
26450 isDecrypted() {
26451 return null;
26452 }
26453
26454 /**
26455 * Returns the creation time of the key
26456 * @returns {Date}
26457 */
26458 getCreationTime() {
26459 return this.created;
26460 }
26461
26462 /**
26463 * Calculates the key id of the key
26464 * @returns {module:type/keyid~Keyid} A 8 byte key id.
26465 */
26466 getKeyId() {
26467 if (this.keyid) {
26468 return this.keyid;
26469 }
26470 this.keyid = new Keyid();
26471 if (this.version === 5) {
26472 this.keyid.read(util.hexToUint8Array(this.getFingerprint()).subarray(0, 8));
26473 } else if (this.version === 4) {
26474 this.keyid.read(util.hexToUint8Array(this.getFingerprint()).subarray(12, 20));
26475 }
26476 return this.keyid;
26477 }
26478
26479 /**
26480 * Calculates the fingerprint of the key
26481 * @returns {Uint8Array} A Uint8Array containing the fingerprint.
26482 */
26483 getFingerprintBytes() {
26484 if (this.fingerprint) {
26485 return this.fingerprint;
26486 }
26487 const toHash = this.writeForHash(this.version);
26488 if (this.version === 5) {
26489 this.fingerprint = Sha256.bytes(toHash);
26490 } else if (this.version === 4) {
26491 this.fingerprint = Sha1.bytes(toHash);
26492 }
26493 return this.fingerprint;
26494 }
26495
26496 /**
26497 * Calculates the fingerprint of the key
26498 * @returns {String} A string containing the fingerprint in lowercase hex.
26499 */
26500 getFingerprint() {
26501 return util.uint8ArrayToHex(this.getFingerprintBytes());
26502 }
26503
26504 /**
26505 * Calculates whether two keys have the same fingerprint without actually calculating the fingerprint
26506 * @returns {Boolean} Whether the two keys have the same version and public key data.
26507 */
26508 hasSameFingerprintAs(other) {
26509 return this.version === other.version && util.equalsUint8Array(this.writePublicKey(), other.writePublicKey());
26510 }
26511
26512 /**
26513 * Returns algorithm information
26514 * @returns {Object} An object of the form {algorithm: String, bits:int, curve:String}.
26515 */
26516 getAlgorithmInfo() {
26517 const result = {};
26518 result.algorithm = this.algorithm;
26519 // RSA, DSA or ElGamal public modulo
26520 const modulo = this.publicParams.n || this.publicParams.p;
26521 if (modulo) {
26522 result.bits = modulo.length * 8;
26523 } else {
26524 result.curve = this.publicParams.oid.getName();
26525 }
26526 return result;
26527 }
26528}
26529
26530/**
26531 * Alias of read()
26532 * @see PublicKeyPacket#read
26533 */
26534PublicKeyPacket.prototype.readPublicKey = PublicKeyPacket.prototype.read;
26535
26536/**
26537 * Alias of write()
26538 * @see PublicKeyPacket#write
26539 */
26540PublicKeyPacket.prototype.writePublicKey = PublicKeyPacket.prototype.write;
26541
26542// GPG4Browsers - An OpenPGP implementation in javascript
26543
26544/**
26545 * Implementation of the Symmetrically Encrypted Data Packet (Tag 9)
26546 *
26547 * {@link https://tools.ietf.org/html/rfc4880#section-5.7|RFC4880 5.7}:
26548 * The Symmetrically Encrypted Data packet contains data encrypted with a
26549 * symmetric-key algorithm. When it has been decrypted, it contains other
26550 * packets (usually a literal data packet or compressed data packet, but in
26551 * theory other Symmetrically Encrypted Data packets or sequences of packets
26552 * that form whole OpenPGP messages).
26553 */
26554class SymmetricallyEncryptedDataPacket {
26555 constructor() {
26556 /**
26557 * Packet type
26558 * @type {module:enums.packet}
26559 */
26560 this.tag = enums.packet.symmetricallyEncryptedData;
26561 /**
26562 * Encrypted secret-key data
26563 */
26564 this.encrypted = null;
26565 /**
26566 * Decrypted packets contained within.
26567 * @type {PacketList}
26568 */
26569 this.packets = null;
26570 }
26571
26572 read(bytes) {
26573 this.encrypted = bytes;
26574 }
26575
26576 write() {
26577 return this.encrypted;
26578 }
26579
26580 /**
26581 * Decrypt the symmetrically-encrypted packet data
26582 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
26583 * @param {module:enums.symmetric} sessionKeyAlgorithm - Symmetric key algorithm to use
26584 * @param {Uint8Array} key - The key of cipher blocksize length to be used
26585 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26586
26587 * @throws {Error} if decryption was not successful
26588 * @async
26589 */
26590 async decrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
26591 // If MDC errors are not being ignored, all missing MDC packets in symmetrically encrypted data should throw an error
26592 if (!config.allowUnauthenticatedMessages) {
26593 throw new Error('Message is not authenticated.');
26594 }
26595
26596 const encrypted = await stream.readToEnd(stream.clone(this.encrypted));
26597 const decrypted = await mod.cfb.decrypt(sessionKeyAlgorithm, key,
26598 encrypted.subarray(mod.cipher[sessionKeyAlgorithm].blockSize + 2),
26599 encrypted.subarray(2, mod.cipher[sessionKeyAlgorithm].blockSize + 2)
26600 );
26601
26602 await this.packets.read(decrypted, {
26603 LiteralDataPacket,
26604 CompressedDataPacket,
26605 OnePassSignaturePacket,
26606 SignaturePacket
26607 }, streaming);
26608 }
26609
26610 /**
26611 * Encrypt the symmetrically-encrypted packet data
26612 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
26613 * @param {module:enums.symmetric} sessionKeyAlgorithm - Symmetric key algorithm to use
26614 * @param {Uint8Array} key - The key of cipher blocksize length to be used
26615 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26616 * @throws {Error} if encryption was not successful
26617 * @async
26618 */
26619 async encrypt(algo, key, streaming, config = defaultConfig) {
26620 const data = this.packets.write();
26621
26622 const prefix = await mod.getPrefixRandom(algo);
26623 const FRE = await mod.cfb.encrypt(algo, key, prefix, new Uint8Array(mod.cipher[algo].blockSize), config);
26624 const ciphertext = await mod.cfb.encrypt(algo, key, data, FRE.subarray(2), config);
26625 this.encrypted = util.concat([FRE, ciphertext]);
26626 }
26627}
26628
26629// GPG4Browsers - An OpenPGP implementation in javascript
26630
26631/**
26632 * Implementation of the strange "Marker packet" (Tag 10)
26633 *
26634 * {@link https://tools.ietf.org/html/rfc4880#section-5.8|RFC4880 5.8}:
26635 * An experimental version of PGP used this packet as the Literal
26636 * packet, but no released version of PGP generated Literal packets with this
26637 * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as
26638 * the Marker packet.
26639 *
26640 * Such a packet MUST be ignored when received.
26641 */
26642class MarkerPacket {
26643 constructor() {
26644 this.tag = enums.packet.marker;
26645 }
26646
26647 /**
26648 * Parsing function for a literal data packet (tag 10).
26649 *
26650 * @param {String} input - Payload of a tag 10 packet
26651 * @param {Integer} position
26652 * Position to start reading from the input string
26653 * @param {Integer} len
26654 * Length of the packet or the remaining length of
26655 * input at position
26656 * @returns {MarkerPacket} Object representation.
26657 */
26658 read(bytes) {
26659 if (bytes[0] === 0x50 && // P
26660 bytes[1] === 0x47 && // G
26661 bytes[2] === 0x50) { // P
26662 return true;
26663 }
26664 // marker packet does not contain "PGP"
26665 return false;
26666 }
26667}
26668
26669// GPG4Browsers - An OpenPGP implementation in javascript
26670
26671/**
26672 * A Public-Subkey packet (tag 14) has exactly the same format as a
26673 * Public-Key packet, but denotes a subkey. One or more subkeys may be
26674 * associated with a top-level key. By convention, the top-level key
26675 * provides signature services, and the subkeys provide encryption
26676 * services.
26677 * @extends PublicKeyPacket
26678 */
26679class PublicSubkeyPacket extends PublicKeyPacket {
26680 /**
26681 * @param {Date} [date] - Creation date
26682 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26683 */
26684 constructor(date, config) {
26685 super(date, config);
26686 this.tag = enums.packet.publicSubkey;
26687 }
26688}
26689
26690// GPG4Browsers - An OpenPGP implementation in javascript
26691
26692function readSimpleLength(bytes) {
26693 let len = 0;
26694 let offset;
26695 const type = bytes[0];
26696
26697
26698 if (type < 192) {
26699 [len] = bytes;
26700 offset = 1;
26701 } else if (type < 255) {
26702 len = ((bytes[0] - 192) << 8) + (bytes[1]) + 192;
26703 offset = 2;
26704 } else if (type === 255) {
26705 len = util.readNumber(bytes.subarray(1, 1 + 4));
26706 offset = 5;
26707 }
26708
26709 return {
26710 len: len,
26711 offset: offset
26712 };
26713}
26714
26715/**
26716 * Encodes a given integer of length to the openpgp length specifier to a
26717 * string
26718 *
26719 * @param {Integer} length - The length to encode
26720 * @returns {Uint8Array} String with openpgp length representation.
26721 */
26722function writeSimpleLength(length) {
26723 if (length < 192) {
26724 return new Uint8Array([length]);
26725 } else if (length > 191 && length < 8384) {
26726 /*
26727 * let a = (total data packet length) - 192 let bc = two octet
26728 * representation of a let d = b + 192
26729 */
26730 return new Uint8Array([((length - 192) >> 8) + 192, (length - 192) & 0xFF]);
26731 }
26732 return util.concatUint8Array([new Uint8Array([255]), util.writeNumber(length, 4)]);
26733}
26734
26735function writePartialLength(power) {
26736 if (power < 0 || power > 30) {
26737 throw new Error('Partial Length power must be between 1 and 30');
26738 }
26739 return new Uint8Array([224 + power]);
26740}
26741
26742function writeTag(tag_type) {
26743 /* we're only generating v4 packet headers here */
26744 return new Uint8Array([0xC0 | tag_type]);
26745}
26746
26747/**
26748 * Writes a packet header version 4 with the given tag_type and length to a
26749 * string
26750 *
26751 * @param {Integer} tag_type - Tag type
26752 * @param {Integer} length - Length of the payload
26753 * @returns {String} String of the header.
26754 */
26755function writeHeader(tag_type, length) {
26756 /* we're only generating v4 packet headers here */
26757 return util.concatUint8Array([writeTag(tag_type), writeSimpleLength(length)]);
26758}
26759
26760/**
26761 * Whether the packet type supports partial lengths per RFC4880
26762 * @param {Integer} tag_type - Tag type
26763 * @returns {Boolean} String of the header.
26764 */
26765function supportsStreaming(tag_type) {
26766 return [
26767 enums.packet.literalData,
26768 enums.packet.compressedData,
26769 enums.packet.symmetricallyEncryptedData,
26770 enums.packet.symEncryptedIntegrityProtectedData,
26771 enums.packet.AEADEncryptedData
26772 ].includes(tag_type);
26773}
26774
26775/**
26776 * Generic static Packet Parser function
26777 *
26778 * @param {Uint8Array | ReadableStream<Uint8Array>} input - Input stream as string
26779 * @param {Function} callback - Function to call with the parsed packet
26780 * @returns {Boolean} Returns false if the stream was empty and parsing is done, and true otherwise.
26781 */
26782async function readPackets(input, streaming, callback) {
26783 const reader = stream.getReader(input);
26784 let writer;
26785 let callbackReturned;
26786 try {
26787 const peekedBytes = await reader.peekBytes(2);
26788 // some sanity checks
26789 if (!peekedBytes || peekedBytes.length < 2 || (peekedBytes[0] & 0x80) === 0) {
26790 throw new Error("Error during parsing. This message / key probably does not conform to a valid OpenPGP format.");
26791 }
26792 const headerByte = await reader.readByte();
26793 let tag = -1;
26794 let format = -1;
26795 let packet_length;
26796
26797 format = 0; // 0 = old format; 1 = new format
26798 if ((headerByte & 0x40) !== 0) {
26799 format = 1;
26800 }
26801
26802 let packet_length_type;
26803 if (format) {
26804 // new format header
26805 tag = headerByte & 0x3F; // bit 5-0
26806 } else {
26807 // old format header
26808 tag = (headerByte & 0x3F) >> 2; // bit 5-2
26809 packet_length_type = headerByte & 0x03; // bit 1-0
26810 }
26811
26812 const packetSupportsStreaming = supportsStreaming(tag);
26813 let packet = null;
26814 if (streaming && packetSupportsStreaming) {
26815 const transform = new stream.TransformStream();
26816 writer = stream.getWriter(transform.writable);
26817 packet = transform.readable;
26818 callbackReturned = callback({ tag, packet });
26819 } else {
26820 packet = [];
26821 }
26822
26823 let wasPartialLength;
26824 do {
26825 if (!format) {
26826 // 4.2.1. Old Format Packet Lengths
26827 switch (packet_length_type) {
26828 case 0:
26829 // The packet has a one-octet length. The header is 2 octets
26830 // long.
26831 packet_length = await reader.readByte();
26832 break;
26833 case 1:
26834 // The packet has a two-octet length. The header is 3 octets
26835 // long.
26836 packet_length = (await reader.readByte() << 8) | await reader.readByte();
26837 break;
26838 case 2:
26839 // The packet has a four-octet length. The header is 5
26840 // octets long.
26841 packet_length = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() <<
26842 8) | await reader.readByte();
26843 break;
26844 default:
26845 // 3 - The packet is of indeterminate length. The header is 1
26846 // octet long, and the implementation must determine how long
26847 // the packet is. If the packet is in a file, this means that
26848 // the packet extends until the end of the file. In general,
26849 // an implementation SHOULD NOT use indeterminate-length
26850 // packets except where the end of the data will be clear
26851 // from the context, and even then it is better to use a
26852 // definite length, or a new format header. The new format
26853 // headers described below have a mechanism for precisely
26854 // encoding data of indeterminate length.
26855 packet_length = Infinity;
26856 break;
26857 }
26858 } else { // 4.2.2. New Format Packet Lengths
26859 // 4.2.2.1. One-Octet Lengths
26860 const lengthByte = await reader.readByte();
26861 wasPartialLength = false;
26862 if (lengthByte < 192) {
26863 packet_length = lengthByte;
26864 // 4.2.2.2. Two-Octet Lengths
26865 } else if (lengthByte >= 192 && lengthByte < 224) {
26866 packet_length = ((lengthByte - 192) << 8) + (await reader.readByte()) + 192;
26867 // 4.2.2.4. Partial Body Lengths
26868 } else if (lengthByte > 223 && lengthByte < 255) {
26869 packet_length = 1 << (lengthByte & 0x1F);
26870 wasPartialLength = true;
26871 if (!packetSupportsStreaming) {
26872 throw new TypeError('This packet type does not support partial lengths.');
26873 }
26874 // 4.2.2.3. Five-Octet Lengths
26875 } else {
26876 packet_length = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() <<
26877 8) | await reader.readByte();
26878 }
26879 }
26880 if (packet_length > 0) {
26881 let bytesRead = 0;
26882 while (true) {
26883 if (writer) await writer.ready;
26884 const { done, value } = await reader.read();
26885 if (done) {
26886 if (packet_length === Infinity) break;
26887 throw new Error('Unexpected end of packet');
26888 }
26889 const chunk = packet_length === Infinity ? value : value.subarray(0, packet_length - bytesRead);
26890 if (writer) await writer.write(chunk);
26891 else packet.push(chunk);
26892 bytesRead += value.length;
26893 if (bytesRead >= packet_length) {
26894 reader.unshift(value.subarray(packet_length - bytesRead + value.length));
26895 break;
26896 }
26897 }
26898 }
26899 } while (wasPartialLength);
26900
26901 // If this was not a packet that "supports streaming", we peek to check
26902 // whether it is the last packet in the message. We peek 2 bytes instead
26903 // of 1 because the beginning of this function also peeks 2 bytes, and we
26904 // want to cut a `subarray` of the correct length into `web-stream-tools`'
26905 // `externalBuffer` as a tiny optimization here.
26906 //
26907 // If it *was* a streaming packet (i.e. the data packets), we peek at the
26908 // entire remainder of the stream, in order to forward errors in the
26909 // remainder of the stream to the packet data. (Note that this means we
26910 // read/peek at all signature packets before closing the literal data
26911 // packet, for example.) This forwards MDC errors to the literal data
26912 // stream, for example, so that they don't get lost / forgotten on
26913 // decryptedMessage.packets.stream, which we never look at.
26914 //
26915 // An example of what we do when stream-parsing a message containing
26916 // [ one-pass signature packet, literal data packet, signature packet ]:
26917 // 1. Read the one-pass signature packet
26918 // 2. Peek 2 bytes of the literal data packet
26919 // 3. Parse the one-pass signature packet
26920 //
26921 // 4. Read the literal data packet, simultaneously stream-parsing it
26922 // 5. Peek until the end of the message
26923 // 6. Finish parsing the literal data packet
26924 //
26925 // 7. Read the signature packet again (we already peeked at it in step 5)
26926 // 8. Peek at the end of the stream again (`peekBytes` returns undefined)
26927 // 9. Parse the signature packet
26928 //
26929 // Note that this means that if there's an error in the very end of the
26930 // stream, such as an MDC error, we throw in step 5 instead of in step 8
26931 // (or never), which is the point of this exercise.
26932 const nextPacket = await reader.peekBytes(packetSupportsStreaming ? Infinity : 2);
26933 if (writer) {
26934 await writer.ready;
26935 await writer.close();
26936 } else {
26937 packet = util.concatUint8Array(packet);
26938 await callback({ tag, packet });
26939 }
26940 return !nextPacket || !nextPacket.length;
26941 } catch (e) {
26942 if (writer) {
26943 await writer.abort(e);
26944 return true;
26945 } else {
26946 throw e;
26947 }
26948 } finally {
26949 if (writer) {
26950 await callbackReturned;
26951 }
26952 reader.releaseLock();
26953 }
26954}
26955
26956// GPG4Browsers - An OpenPGP implementation in javascript
26957
26958/**
26959 * Implementation of the User Attribute Packet (Tag 17)
26960 *
26961 * The User Attribute packet is a variation of the User ID packet. It
26962 * is capable of storing more types of data than the User ID packet,
26963 * which is limited to text. Like the User ID packet, a User Attribute
26964 * packet may be certified by the key owner ("self-signed") or any other
26965 * key owner who cares to certify it. Except as noted, a User Attribute
26966 * packet may be used anywhere that a User ID packet may be used.
26967 *
26968 * While User Attribute packets are not a required part of the OpenPGP
26969 * standard, implementations SHOULD provide at least enough
26970 * compatibility to properly handle a certification signature on the
26971 * User Attribute packet. A simple way to do this is by treating the
26972 * User Attribute packet as a User ID packet with opaque contents, but
26973 * an implementation may use any method desired.
26974 */
26975class UserAttributePacket {
26976 constructor() {
26977 this.tag = enums.packet.userAttribute;
26978 this.attributes = [];
26979 }
26980
26981 /**
26982 * parsing function for a user attribute packet (tag 17).
26983 * @param {Uint8Array} input - Payload of a tag 17 packet
26984 */
26985 read(bytes) {
26986 let i = 0;
26987 while (i < bytes.length) {
26988 const len = readSimpleLength(bytes.subarray(i, bytes.length));
26989 i += len.offset;
26990
26991 this.attributes.push(util.uint8ArrayToStr(bytes.subarray(i, i + len.len)));
26992 i += len.len;
26993 }
26994 }
26995
26996 /**
26997 * Creates a binary representation of the user attribute packet
26998 * @returns {Uint8Array} String representation.
26999 */
27000 write() {
27001 const arr = [];
27002 for (let i = 0; i < this.attributes.length; i++) {
27003 arr.push(writeSimpleLength(this.attributes[i].length));
27004 arr.push(util.strToUint8Array(this.attributes[i]));
27005 }
27006 return util.concatUint8Array(arr);
27007 }
27008
27009 /**
27010 * Compare for equality
27011 * @param {UserAttributePacket} usrAttr
27012 * @returns {Boolean} True if equal.
27013 */
27014 equals(usrAttr) {
27015 if (!usrAttr || !(usrAttr instanceof UserAttributePacket)) {
27016 return false;
27017 }
27018 return this.attributes.every(function(attr, index) {
27019 return attr === usrAttr.attributes[index];
27020 });
27021 }
27022}
27023
27024// GPG4Browsers - An OpenPGP implementation in javascript
27025
27026/**
27027 * Implementation of the Signature Packet (Tag 2)
27028 *
27029 * {@link https://tools.ietf.org/html/rfc4880#section-5.2|RFC4480 5.2}:
27030 * A Signature packet describes a binding between some public key and
27031 * some data. The most common signatures are a signature of a file or a
27032 * block of text, and a signature that is a certification of a User ID.
27033 */
27034class SignaturePacket {
27035 /**
27036 * @param {Date} date - The creation date of the signature
27037 */
27038 constructor(date = new Date()) {
27039 this.tag = enums.packet.signature;
27040 this.version = 4; // This is set to 5 below if we sign with a V5 key.
27041 this.signatureType = null;
27042 this.hashAlgorithm = null;
27043 this.publicKeyAlgorithm = null;
27044
27045 this.signatureData = null;
27046 this.unhashedSubpackets = [];
27047 this.signedHashValue = null;
27048
27049 this.created = util.normalizeDate(date);
27050 this.signatureExpirationTime = null;
27051 this.signatureNeverExpires = true;
27052 this.exportable = null;
27053 this.trustLevel = null;
27054 this.trustAmount = null;
27055 this.regularExpression = null;
27056 this.revocable = null;
27057 this.keyExpirationTime = null;
27058 this.keyNeverExpires = null;
27059 this.preferredSymmetricAlgorithms = null;
27060 this.revocationKeyClass = null;
27061 this.revocationKeyAlgorithm = null;
27062 this.revocationKeyFingerprint = null;
27063 this.issuerKeyId = new Keyid();
27064 this.rawNotations = [];
27065 this.notations = {};
27066 this.preferredHashAlgorithms = null;
27067 this.preferredCompressionAlgorithms = null;
27068 this.keyServerPreferences = null;
27069 this.preferredKeyServer = null;
27070 this.isPrimaryUserID = null;
27071 this.policyURI = null;
27072 this.keyFlags = null;
27073 this.signersUserId = null;
27074 this.reasonForRevocationFlag = null;
27075 this.reasonForRevocationString = null;
27076 this.features = null;
27077 this.signatureTargetPublicKeyAlgorithm = null;
27078 this.signatureTargetHashAlgorithm = null;
27079 this.signatureTargetHash = null;
27080 this.embeddedSignature = null;
27081 this.issuerKeyVersion = null;
27082 this.issuerFingerprint = null;
27083 this.preferredAeadAlgorithms = null;
27084
27085 this.verified = null;
27086 this.revoked = null;
27087 }
27088
27089 /**
27090 * parsing function for a signature packet (tag 2).
27091 * @param {String} bytes - Payload of a tag 2 packet
27092 * @returns {SignaturePacket} Object representation.
27093 */
27094 read(bytes) {
27095 let i = 0;
27096 this.version = bytes[i++];
27097
27098 if (this.version !== 4 && this.version !== 5) {
27099 throw new Error('Version ' + this.version + ' of the signature is unsupported.');
27100 }
27101
27102 this.signatureType = bytes[i++];
27103 this.publicKeyAlgorithm = bytes[i++];
27104 this.hashAlgorithm = bytes[i++];
27105
27106 // hashed subpackets
27107 i += this.read_sub_packets(bytes.subarray(i, bytes.length), true);
27108
27109 // A V4 signature hashes the packet body
27110 // starting from its first field, the version number, through the end
27111 // of the hashed subpacket data. Thus, the fields hashed are the
27112 // signature version, the signature type, the public-key algorithm, the
27113 // hash algorithm, the hashed subpacket length, and the hashed
27114 // subpacket body.
27115 this.signatureData = bytes.subarray(0, i);
27116
27117 // unhashed subpackets
27118 i += this.read_sub_packets(bytes.subarray(i, bytes.length), false);
27119
27120 // Two-octet field holding left 16 bits of signed hash value.
27121 this.signedHashValue = bytes.subarray(i, i + 2);
27122 i += 2;
27123
27124 this.params = mod.signature.parseSignatureParams(this.publicKeyAlgorithm, bytes.subarray(i, bytes.length));
27125 }
27126
27127 /**
27128 * @returns {Uint8Array | ReadableStream<Uint8Array>}
27129 */
27130 write_params() {
27131 if (this.params instanceof Promise) {
27132 return stream.fromAsync(
27133 async () => mod.serializeParams(this.publicKeyAlgorithm, await this.params)
27134 );
27135 }
27136 return mod.serializeParams(this.publicKeyAlgorithm, this.params);
27137 }
27138
27139 write() {
27140 const arr = [];
27141 arr.push(this.signatureData);
27142 arr.push(this.write_unhashed_sub_packets());
27143 arr.push(this.signedHashValue);
27144 arr.push(this.write_params());
27145 return util.concat(arr);
27146 }
27147
27148 /**
27149 * Signs provided data. This needs to be done prior to serialization.
27150 * @param {SecretKeyPacket} key - Private key used to sign the message.
27151 * @param {Object} data - Contains packets to be signed.
27152 * @param {Boolean} [detached] - Whether to create a detached signature
27153 * @param {Boolean} [streaming] - Whether to process data as a stream
27154 * @throws {Error} if signing failed
27155 * @async
27156 */
27157 async sign(key, data, detached = false, streaming = false) {
27158 const signatureType = enums.write(enums.signature, this.signatureType);
27159 const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
27160 const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
27161
27162 if (key.version === 5) {
27163 this.version = 5;
27164 }
27165 const arr = [new Uint8Array([this.version, signatureType, publicKeyAlgorithm, hashAlgorithm])];
27166
27167 this.issuerKeyVersion = key.version;
27168 this.issuerFingerprint = key.getFingerprintBytes();
27169 this.issuerKeyId = key.getKeyId();
27170
27171 // Add hashed subpackets
27172 arr.push(this.write_hashed_sub_packets());
27173
27174 this.signatureData = util.concat(arr);
27175
27176 const toHash = this.toHash(signatureType, data, detached);
27177 const hash = await this.hash(signatureType, data, toHash, detached);
27178
27179 this.signedHashValue = stream.slice(stream.clone(hash), 0, 2);
27180 const signed = async () => mod.signature.sign(
27181 publicKeyAlgorithm, hashAlgorithm, key.publicParams, key.privateParams, toHash, await stream.readToEnd(hash)
27182 );
27183 if (streaming) {
27184 this.params = signed();
27185 } else {
27186 this.params = await signed();
27187
27188 // Store the fact that this signature is valid, e.g. for when we call `await
27189 // getLatestValidSignature(this.revocationSignatures, key, data)` later.
27190 // Note that this only holds up if the key and data passed to verify are the
27191 // same as the ones passed to sign.
27192 this.verified = true;
27193 }
27194 }
27195
27196 /**
27197 * Creates Uint8Array of bytes of all subpacket data except Issuer and Embedded Signature subpackets
27198 * @returns {Uint8Array} Subpacket data.
27199 */
27200 write_hashed_sub_packets() {
27201 const sub = enums.signatureSubpacket;
27202 const arr = [];
27203 let bytes;
27204 if (this.created !== null) {
27205 arr.push(write_sub_packet(sub.signatureCreationTime, util.writeDate(this.created)));
27206 }
27207 if (this.signatureExpirationTime !== null) {
27208 arr.push(write_sub_packet(sub.signatureExpirationTime, util.writeNumber(this.signatureExpirationTime, 4)));
27209 }
27210 if (this.exportable !== null) {
27211 arr.push(write_sub_packet(sub.exportableCertification, new Uint8Array([this.exportable ? 1 : 0])));
27212 }
27213 if (this.trustLevel !== null) {
27214 bytes = new Uint8Array([this.trustLevel, this.trustAmount]);
27215 arr.push(write_sub_packet(sub.trustSignature, bytes));
27216 }
27217 if (this.regularExpression !== null) {
27218 arr.push(write_sub_packet(sub.regularExpression, this.regularExpression));
27219 }
27220 if (this.revocable !== null) {
27221 arr.push(write_sub_packet(sub.revocable, new Uint8Array([this.revocable ? 1 : 0])));
27222 }
27223 if (this.keyExpirationTime !== null) {
27224 arr.push(write_sub_packet(sub.keyExpirationTime, util.writeNumber(this.keyExpirationTime, 4)));
27225 }
27226 if (this.preferredSymmetricAlgorithms !== null) {
27227 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredSymmetricAlgorithms));
27228 arr.push(write_sub_packet(sub.preferredSymmetricAlgorithms, bytes));
27229 }
27230 if (this.revocationKeyClass !== null) {
27231 bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]);
27232 bytes = util.concat([bytes, this.revocationKeyFingerprint]);
27233 arr.push(write_sub_packet(sub.revocationKey, bytes));
27234 }
27235 this.rawNotations.forEach(([{ name, value, humanReadable }]) => {
27236 bytes = [new Uint8Array([humanReadable ? 0x80 : 0, 0, 0, 0])];
27237 // 2 octets of name length
27238 bytes.push(util.writeNumber(name.length, 2));
27239 // 2 octets of value length
27240 bytes.push(util.writeNumber(value.length, 2));
27241 bytes.push(util.strToUint8Array(name));
27242 bytes.push(value);
27243 bytes = util.concat(bytes);
27244 arr.push(write_sub_packet(sub.notationData, bytes));
27245 });
27246 if (this.preferredHashAlgorithms !== null) {
27247 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredHashAlgorithms));
27248 arr.push(write_sub_packet(sub.preferredHashAlgorithms, bytes));
27249 }
27250 if (this.preferredCompressionAlgorithms !== null) {
27251 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredCompressionAlgorithms));
27252 arr.push(write_sub_packet(sub.preferredCompressionAlgorithms, bytes));
27253 }
27254 if (this.keyServerPreferences !== null) {
27255 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.keyServerPreferences));
27256 arr.push(write_sub_packet(sub.keyServerPreferences, bytes));
27257 }
27258 if (this.preferredKeyServer !== null) {
27259 arr.push(write_sub_packet(sub.preferredKeyServer, util.strToUint8Array(this.preferredKeyServer)));
27260 }
27261 if (this.isPrimaryUserID !== null) {
27262 arr.push(write_sub_packet(sub.primaryUserId, new Uint8Array([this.isPrimaryUserID ? 1 : 0])));
27263 }
27264 if (this.policyURI !== null) {
27265 arr.push(write_sub_packet(sub.policyUri, util.strToUint8Array(this.policyURI)));
27266 }
27267 if (this.keyFlags !== null) {
27268 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.keyFlags));
27269 arr.push(write_sub_packet(sub.keyFlags, bytes));
27270 }
27271 if (this.signersUserId !== null) {
27272 arr.push(write_sub_packet(sub.signersUserId, util.strToUint8Array(this.signersUserId)));
27273 }
27274 if (this.reasonForRevocationFlag !== null) {
27275 bytes = util.strToUint8Array(String.fromCharCode(this.reasonForRevocationFlag) + this.reasonForRevocationString);
27276 arr.push(write_sub_packet(sub.reasonForRevocation, bytes));
27277 }
27278 if (this.features !== null) {
27279 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.features));
27280 arr.push(write_sub_packet(sub.features, bytes));
27281 }
27282 if (this.signatureTargetPublicKeyAlgorithm !== null) {
27283 bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
27284 bytes.push(util.strToUint8Array(this.signatureTargetHash));
27285 bytes = util.concat(bytes);
27286 arr.push(write_sub_packet(sub.signatureTarget, bytes));
27287 }
27288 if (this.preferredAeadAlgorithms !== null) {
27289 bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredAeadAlgorithms));
27290 arr.push(write_sub_packet(sub.preferredAeadAlgorithms, bytes));
27291 }
27292
27293 const result = util.concat(arr);
27294 const length = util.writeNumber(result.length, 2);
27295
27296 return util.concat([length, result]);
27297 }
27298
27299 /**
27300 * Creates Uint8Array of bytes of Issuer and Embedded Signature subpackets
27301 * @returns {Uint8Array} Subpacket data.
27302 */
27303 write_unhashed_sub_packets() {
27304 const sub = enums.signatureSubpacket;
27305 const arr = [];
27306 let bytes;
27307 if (!this.issuerKeyId.isNull() && this.issuerKeyVersion !== 5) {
27308 // If the version of [the] key is greater than 4, this subpacket
27309 // MUST NOT be included in the signature.
27310 arr.push(write_sub_packet(sub.issuer, this.issuerKeyId.write()));
27311 }
27312 if (this.embeddedSignature !== null) {
27313 arr.push(write_sub_packet(sub.embeddedSignature, this.embeddedSignature.write()));
27314 }
27315 if (this.issuerFingerprint !== null) {
27316 bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
27317 bytes = util.concat(bytes);
27318 arr.push(write_sub_packet(sub.issuerFingerprint, bytes));
27319 }
27320 this.unhashedSubpackets.forEach(data => {
27321 arr.push(writeSimpleLength(data.length));
27322 arr.push(data);
27323 });
27324
27325 const result = util.concat(arr);
27326 const length = util.writeNumber(result.length, 2);
27327
27328 return util.concat([length, result]);
27329 }
27330
27331 // V4 signature sub packets
27332
27333 read_sub_packet(bytes, trusted = true) {
27334 let mypos = 0;
27335
27336 const read_array = (prop, bytes) => {
27337 this[prop] = [];
27338
27339 for (let i = 0; i < bytes.length; i++) {
27340 this[prop].push(bytes[i]);
27341 }
27342 };
27343
27344 // The leftmost bit denotes a "critical" packet
27345 const critical = bytes[mypos] & 0x80;
27346 const type = bytes[mypos] & 0x7F;
27347
27348 // GPG puts the Issuer and Signature subpackets in the unhashed area.
27349 // Tampering with those invalidates the signature, so we can trust them.
27350 // Ignore all other unhashed subpackets.
27351 if (!trusted && ![
27352 enums.signatureSubpacket.issuer,
27353 enums.signatureSubpacket.issuerFingerprint,
27354 enums.signatureSubpacket.embeddedSignature
27355 ].includes(type)) {
27356 this.unhashedSubpackets.push(bytes.subarray(mypos, bytes.length));
27357 return;
27358 }
27359
27360 mypos++;
27361
27362 // subpacket type
27363 switch (type) {
27364 case 2:
27365 // Signature Creation Time
27366 this.created = util.readDate(bytes.subarray(mypos, bytes.length));
27367 break;
27368 case 3: {
27369 // Signature Expiration Time in seconds
27370 const seconds = util.readNumber(bytes.subarray(mypos, bytes.length));
27371
27372 this.signatureNeverExpires = seconds === 0;
27373 this.signatureExpirationTime = seconds;
27374
27375 break;
27376 }
27377 case 4:
27378 // Exportable Certification
27379 this.exportable = bytes[mypos++] === 1;
27380 break;
27381 case 5:
27382 // Trust Signature
27383 this.trustLevel = bytes[mypos++];
27384 this.trustAmount = bytes[mypos++];
27385 break;
27386 case 6:
27387 // Regular Expression
27388 this.regularExpression = bytes[mypos];
27389 break;
27390 case 7:
27391 // Revocable
27392 this.revocable = bytes[mypos++] === 1;
27393 break;
27394 case 9: {
27395 // Key Expiration Time in seconds
27396 const seconds = util.readNumber(bytes.subarray(mypos, bytes.length));
27397
27398 this.keyExpirationTime = seconds;
27399 this.keyNeverExpires = seconds === 0;
27400
27401 break;
27402 }
27403 case 11:
27404 // Preferred Symmetric Algorithms
27405 read_array('preferredSymmetricAlgorithms', bytes.subarray(mypos, bytes.length));
27406 break;
27407 case 12:
27408 // Revocation Key
27409 // (1 octet of class, 1 octet of public-key algorithm ID, 20
27410 // octets of
27411 // fingerprint)
27412 this.revocationKeyClass = bytes[mypos++];
27413 this.revocationKeyAlgorithm = bytes[mypos++];
27414 this.revocationKeyFingerprint = bytes.subarray(mypos, mypos + 20);
27415 break;
27416
27417 case 16:
27418 // Issuer
27419 this.issuerKeyId.read(bytes.subarray(mypos, bytes.length));
27420 break;
27421
27422 case 20: {
27423 // Notation Data
27424 const humanReadable = !!(bytes[mypos] & 0x80);
27425
27426 // We extract key/value tuple from the byte stream.
27427 mypos += 4;
27428 const m = util.readNumber(bytes.subarray(mypos, mypos + 2));
27429 mypos += 2;
27430 const n = util.readNumber(bytes.subarray(mypos, mypos + 2));
27431 mypos += 2;
27432
27433 const name = util.uint8ArrayToStr(bytes.subarray(mypos, mypos + m));
27434 const value = bytes.subarray(mypos + m, mypos + m + n);
27435
27436 this.rawNotations.push({ name, humanReadable, value, critical });
27437
27438 if (humanReadable) {
27439 this.notations[name] = util.uint8ArrayToStr(value);
27440 }
27441 break;
27442 }
27443 case 21:
27444 // Preferred Hash Algorithms
27445 read_array('preferredHashAlgorithms', bytes.subarray(mypos, bytes.length));
27446 break;
27447 case 22:
27448 // Preferred Compression Algorithms
27449 read_array('preferredCompressionAlgorithms', bytes.subarray(mypos, bytes.length));
27450 break;
27451 case 23:
27452 // Key Server Preferences
27453 read_array('keyServerPreferences', bytes.subarray(mypos, bytes.length));
27454 break;
27455 case 24:
27456 // Preferred Key Server
27457 this.preferredKeyServer = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length));
27458 break;
27459 case 25:
27460 // Primary User ID
27461 this.isPrimaryUserID = bytes[mypos++] !== 0;
27462 break;
27463 case 26:
27464 // Policy URI
27465 this.policyURI = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length));
27466 break;
27467 case 27:
27468 // Key Flags
27469 read_array('keyFlags', bytes.subarray(mypos, bytes.length));
27470 break;
27471 case 28:
27472 // Signer's User ID
27473 this.signersUserId = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length));
27474 break;
27475 case 29:
27476 // Reason for Revocation
27477 this.reasonForRevocationFlag = bytes[mypos++];
27478 this.reasonForRevocationString = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length));
27479 break;
27480 case 30:
27481 // Features
27482 read_array('features', bytes.subarray(mypos, bytes.length));
27483 break;
27484 case 31: {
27485 // Signature Target
27486 // (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash)
27487 this.signatureTargetPublicKeyAlgorithm = bytes[mypos++];
27488 this.signatureTargetHashAlgorithm = bytes[mypos++];
27489
27490 const len = mod.getHashByteLength(this.signatureTargetHashAlgorithm);
27491
27492 this.signatureTargetHash = util.uint8ArrayToStr(bytes.subarray(mypos, mypos + len));
27493 break;
27494 }
27495 case 32:
27496 // Embedded Signature
27497 this.embeddedSignature = new SignaturePacket();
27498 this.embeddedSignature.read(bytes.subarray(mypos, bytes.length));
27499 break;
27500 case 33:
27501 // Issuer Fingerprint
27502 this.issuerKeyVersion = bytes[mypos++];
27503 this.issuerFingerprint = bytes.subarray(mypos, bytes.length);
27504 if (this.issuerKeyVersion === 5) {
27505 this.issuerKeyId.read(this.issuerFingerprint);
27506 } else {
27507 this.issuerKeyId.read(this.issuerFingerprint.subarray(-8));
27508 }
27509 break;
27510 case 34:
27511 // Preferred AEAD Algorithms
27512 read_array.call(this, 'preferredAeadAlgorithms', bytes.subarray(mypos, bytes.length));
27513 break;
27514 default: {
27515 const err = new Error("Unknown signature subpacket type " + type + " @:" + mypos);
27516 if (critical) {
27517 throw err;
27518 } else {
27519 util.printDebug(err);
27520 }
27521 }
27522 }
27523 }
27524
27525 read_sub_packets(bytes, trusted = true, config) {
27526 // Two-octet scalar octet count for following subpacket data.
27527 const subpacket_length = util.readNumber(bytes.subarray(0, 2));
27528
27529 let i = 2;
27530
27531 // subpacket data set (zero or more subpackets)
27532 while (i < 2 + subpacket_length) {
27533 const len = readSimpleLength(bytes.subarray(i, bytes.length));
27534 i += len.offset;
27535
27536 this.read_sub_packet(bytes.subarray(i, i + len.len), trusted, config);
27537
27538 i += len.len;
27539 }
27540
27541 return i;
27542 }
27543
27544 // Produces data to produce signature on
27545 toSign(type, data) {
27546 const t = enums.signature;
27547
27548 switch (type) {
27549 case t.binary:
27550 if (data.text !== null) {
27551 return util.encodeUtf8(data.getText(true));
27552 }
27553 return data.getBytes(true);
27554
27555 case t.text: {
27556 const bytes = data.getBytes(true);
27557 // normalize EOL to \r\n
27558 return util.canonicalizeEOL(bytes);
27559 }
27560 case t.standalone:
27561 return new Uint8Array(0);
27562
27563 case t.certGeneric:
27564 case t.certPersona:
27565 case t.certCasual:
27566 case t.certPositive:
27567 case t.certRevocation: {
27568 let packet;
27569 let tag;
27570
27571 if (data.userId) {
27572 tag = 0xB4;
27573 packet = data.userId;
27574 } else if (data.userAttribute) {
27575 tag = 0xD1;
27576 packet = data.userAttribute;
27577 } else {
27578 throw new Error('Either a userId or userAttribute packet needs to be ' +
27579 'supplied for certification.');
27580 }
27581
27582 const bytes = packet.write();
27583
27584 return util.concat([this.toSign(t.key, data),
27585 new Uint8Array([tag]),
27586 util.writeNumber(bytes.length, 4),
27587 bytes]);
27588 }
27589 case t.subkeyBinding:
27590 case t.subkeyRevocation:
27591 case t.keyBinding:
27592 return util.concat([this.toSign(t.key, data), this.toSign(t.key, {
27593 key: data.bind
27594 })]);
27595
27596 case t.key:
27597 if (data.key === undefined) {
27598 throw new Error('Key packet is required for this signature.');
27599 }
27600 return data.key.writeForHash(this.version);
27601
27602 case t.keyRevocation:
27603 return this.toSign(t.key, data);
27604 case t.timestamp:
27605 return new Uint8Array(0);
27606 case t.thirdParty:
27607 throw new Error('Not implemented');
27608 default:
27609 throw new Error('Unknown signature type.');
27610 }
27611 }
27612
27613 calculateTrailer(data, detached) {
27614 let length = 0;
27615 return stream.transform(stream.clone(this.signatureData), value => {
27616 length += value.length;
27617 }, () => {
27618 const arr = [];
27619 if (this.version === 5 && (this.signatureType === enums.signature.binary || this.signatureType === enums.signature.text)) {
27620 if (detached) {
27621 arr.push(new Uint8Array(6));
27622 } else {
27623 arr.push(data.writeHeader());
27624 }
27625 }
27626 arr.push(new Uint8Array([this.version, 0xFF]));
27627 if (this.version === 5) {
27628 arr.push(new Uint8Array(4));
27629 }
27630 arr.push(util.writeNumber(length, 4));
27631 // For v5, this should really be writeNumber(length, 8) rather than the
27632 // hardcoded 4 zero bytes above
27633 return util.concat(arr);
27634 });
27635 }
27636
27637 toHash(signatureType, data, detached = false) {
27638 const bytes = this.toSign(signatureType, data);
27639
27640 return util.concat([bytes, this.signatureData, this.calculateTrailer(data, detached)]);
27641 }
27642
27643 async hash(signatureType, data, toHash, detached = false, streaming = true) {
27644 const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
27645 if (!toHash) toHash = this.toHash(signatureType, data, detached);
27646 if (!streaming && util.isStream(toHash)) {
27647 return stream.fromAsync(async () => this.hash(signatureType, data, await stream.readToEnd(toHash), detached));
27648 }
27649 return mod.hash.digest(hashAlgorithm, toHash);
27650 }
27651
27652 /**
27653 * verifies the signature packet. Note: not all signature types are implemented
27654 * @param {PublicSubkeyPacket|PublicKeyPacket|
27655 * SecretSubkeyPacket|SecretKeyPacket} key the public key to verify the signature
27656 * @param {module:enums.signature} signatureType - Expected signature type
27657 * @param {String|Object} data - Data which on the signature applies
27658 * @param {Boolean} [detached] - Whether to verify a detached signature
27659 * @param {Boolean} [streaming] - Whether to process data as a stream
27660 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27661 * @throws {Error} if signature validation failed
27662 * @async
27663 */
27664 async verify(key, signatureType, data, detached = false, streaming = false, config = defaultConfig) {
27665 const publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm);
27666 const hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm);
27667
27668 if (publicKeyAlgorithm !== enums.write(enums.publicKey, key.algorithm)) {
27669 throw new Error('Public key algorithm used to sign signature does not match issuer key algorithm.');
27670 }
27671
27672 let toHash;
27673 let hash;
27674 if (this.hashed) {
27675 hash = await this.hashed;
27676 } else {
27677 toHash = this.toHash(signatureType, data, detached);
27678 if (!streaming) toHash = await stream.readToEnd(toHash);
27679 hash = await this.hash(signatureType, data, toHash);
27680 }
27681 hash = await stream.readToEnd(hash);
27682 if (this.signedHashValue[0] !== hash[0] ||
27683 this.signedHashValue[1] !== hash[1]) {
27684 throw new Error('Message digest did not match');
27685 }
27686
27687 this.params = await this.params;
27688
27689 const verified = await mod.signature.verify(
27690 publicKeyAlgorithm, hashAlgorithm, this.params, key.publicParams,
27691 toHash, hash
27692 );
27693 if (!verified) {
27694 throw new Error('Signature verification failed');
27695 }
27696 if (config.rejectHashAlgorithms.has(hashAlgorithm)) {
27697 throw new Error('Insecure hash algorithm: ' + enums.read(enums.hash, hashAlgorithm).toUpperCase());
27698 }
27699 if (config.rejectMessageHashAlgorithms.has(hashAlgorithm) &&
27700 [enums.signature.binary, enums.signature.text].includes(this.signatureType)) {
27701 throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, hashAlgorithm).toUpperCase());
27702 }
27703 this.rawNotations.forEach(({ name, critical }) => {
27704 if (critical && (config.knownNotations.indexOf(name) < 0)) {
27705 throw new Error(`Unknown critical notation: ${name}`);
27706 }
27707 });
27708 if (this.revocationKeyClass !== null) {
27709 throw new Error('This key is intended to be revoked with an authorized key, which OpenPGP.js does not support.');
27710 }
27711 this.verified = true;
27712 }
27713
27714 /**
27715 * Verifies signature expiration date
27716 * @param {Date} [date] - Use the given date for verification instead of the current time
27717 * @returns {Boolean} True if expired.
27718 */
27719 isExpired(date = new Date()) {
27720 const normDate = util.normalizeDate(date);
27721 if (normDate !== null) {
27722 const expirationTime = this.getExpirationTime();
27723 return !(this.created <= normDate && normDate <= expirationTime);
27724 }
27725 return false;
27726 }
27727
27728 /**
27729 * Returns the expiration time of the signature or Infinity if signature does not expire
27730 * @returns {Date} Expiration time.
27731 */
27732 getExpirationTime() {
27733 return !this.signatureNeverExpires ? new Date(this.created.getTime() + this.signatureExpirationTime * 1000) : Infinity;
27734 }
27735}
27736
27737/**
27738 * Creates a string representation of a sub signature packet
27739 * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.1|RFC4880 5.2.3.1}
27740 * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.2|RFC4880 5.2.3.2}
27741 * @param {Integer} type - Subpacket signature type.
27742 * @param {String} data - Data to be included
27743 * @returns {String} A string-representation of a sub signature packet.
27744 * @private
27745 */
27746function write_sub_packet(type, data) {
27747 const arr = [];
27748 arr.push(writeSimpleLength(data.length + 1));
27749 arr.push(new Uint8Array([type]));
27750 arr.push(data);
27751 return util.concat(arr);
27752}
27753
27754// GPG4Browsers - An OpenPGP implementation in javascript
27755
27756/**
27757 * Implementation of the One-Pass Signature Packets (Tag 4)
27758 *
27759 * {@link https://tools.ietf.org/html/rfc4880#section-5.4|RFC4880 5.4}:
27760 * The One-Pass Signature packet precedes the signed data and contains
27761 * enough information to allow the receiver to begin calculating any
27762 * hashes needed to verify the signature. It allows the Signature
27763 * packet to be placed at the end of the message, so that the signer
27764 * can compute the entire signed message in one pass.
27765 */
27766class OnePassSignaturePacket {
27767 constructor() {
27768 /**
27769 * Packet type
27770 * @type {module:enums.packet}
27771 */
27772 this.tag = enums.packet.onePassSignature;
27773 /** A one-octet version number. The current version is 3. */
27774 this.version = null;
27775 /**
27776 * A one-octet signature type.
27777 * Signature types are described in
27778 * {@link https://tools.ietf.org/html/rfc4880#section-5.2.1|RFC4880 Section 5.2.1}.
27779 */
27780 this.signatureType = null;
27781 /**
27782 * A one-octet number describing the hash algorithm used.
27783 * @see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880 9.4}
27784 */
27785 this.hashAlgorithm = null;
27786 /**
27787 * A one-octet number describing the public-key algorithm used.
27788 * @see {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC4880 9.1}
27789 */
27790 this.publicKeyAlgorithm = null;
27791 /** An eight-octet number holding the Key ID of the signing key. */
27792 this.issuerKeyId = null;
27793 /**
27794 * A one-octet number holding a flag showing whether the signature is nested.
27795 * A zero value indicates that the next packet is another One-Pass Signature packet
27796 * that describes another signature to be applied to the same message data.
27797 */
27798 this.flags = null;
27799 }
27800
27801 /**
27802 * parsing function for a one-pass signature packet (tag 4).
27803 * @param {Uint8Array} bytes - Payload of a tag 4 packet
27804 * @returns {OnePassSignaturePacket} Object representation.
27805 */
27806 read(bytes) {
27807 let mypos = 0;
27808 // A one-octet version number. The current version is 3.
27809 this.version = bytes[mypos++];
27810
27811 // A one-octet signature type. Signature types are described in
27812 // Section 5.2.1.
27813 this.signatureType = bytes[mypos++];
27814
27815 // A one-octet number describing the hash algorithm used.
27816 this.hashAlgorithm = bytes[mypos++];
27817
27818 // A one-octet number describing the public-key algorithm used.
27819 this.publicKeyAlgorithm = bytes[mypos++];
27820
27821 // An eight-octet number holding the Key ID of the signing key.
27822 this.issuerKeyId = new Keyid();
27823 this.issuerKeyId.read(bytes.subarray(mypos, mypos + 8));
27824 mypos += 8;
27825
27826 // A one-octet number holding a flag showing whether the signature
27827 // is nested. A zero value indicates that the next packet is
27828 // another One-Pass Signature packet that describes another
27829 // signature to be applied to the same message data.
27830 this.flags = bytes[mypos++];
27831 return this;
27832 }
27833
27834 /**
27835 * creates a string representation of a one-pass signature packet
27836 * @returns {Uint8Array} A Uint8Array representation of a one-pass signature packet.
27837 */
27838 write() {
27839 const start = new Uint8Array([3, enums.write(enums.signature, this.signatureType),
27840 enums.write(enums.hash, this.hashAlgorithm),
27841 enums.write(enums.publicKey, this.publicKeyAlgorithm)]);
27842
27843 const end = new Uint8Array([this.flags]);
27844
27845 return util.concatUint8Array([start, this.issuerKeyId.write(), end]);
27846 }
27847
27848 calculateTrailer(...args) {
27849 return stream.fromAsync(async () => SignaturePacket.prototype.calculateTrailer.apply(await this.correspondingSig, args));
27850 }
27851
27852 async verify() {
27853 const correspondingSig = await this.correspondingSig;
27854 if (!correspondingSig || correspondingSig.tag !== enums.packet.signature) {
27855 throw new Error('Corresponding signature packet missing');
27856 }
27857 if (
27858 correspondingSig.signatureType !== this.signatureType ||
27859 correspondingSig.hashAlgorithm !== this.hashAlgorithm ||
27860 correspondingSig.publicKeyAlgorithm !== this.publicKeyAlgorithm ||
27861 !correspondingSig.issuerKeyId.equals(this.issuerKeyId)
27862 ) {
27863 throw new Error('Corresponding signature packet does not match one-pass signature packet');
27864 }
27865 correspondingSig.hashed = this.hashed;
27866 return correspondingSig.verify.apply(correspondingSig, arguments);
27867 }
27868}
27869
27870OnePassSignaturePacket.prototype.hash = SignaturePacket.prototype.hash;
27871OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash;
27872OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign;
27873
27874// GPG4Browsers - An OpenPGP implementation in javascript
27875
27876/**
27877 * A Secret-Key packet contains all the information that is found in a
27878 * Public-Key packet, including the public-key material, but also
27879 * includes the secret-key material after all the public-key fields.
27880 * @extends PublicKeyPacket
27881 */
27882class SecretKeyPacket extends PublicKeyPacket {
27883 /**
27884 * @param {Date} [date] - Creation date
27885 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27886 */
27887 constructor(date = new Date(), config = defaultConfig) {
27888 super(date, config);
27889 /**
27890 * Packet type
27891 * @type {module:enums.packet}
27892 */
27893 this.tag = enums.packet.secretKey;
27894 /**
27895 * Secret-key data
27896 */
27897 this.keyMaterial = null;
27898 /**
27899 * Indicates whether secret-key data is encrypted. `this.isEncrypted === false` means data is available in decrypted form.
27900 */
27901 this.isEncrypted = null;
27902 /**
27903 * S2K usage
27904 * @type {Integer}
27905 */
27906 this.s2k_usage = 0;
27907 /**
27908 * S2K object
27909 * @type {type/s2k}
27910 */
27911 this.s2k = null;
27912 /**
27913 * Symmetric algorithm
27914 * @type {String}
27915 */
27916 this.symmetric = null;
27917 /**
27918 * AEAD algorithm
27919 * @type {String}
27920 */
27921 this.aead = null;
27922 /**
27923 * Decrypted private parameters, referenced by name
27924 * @type {Object}
27925 */
27926 this.privateParams = null;
27927 }
27928
27929 // 5.5.3. Secret-Key Packet Formats
27930
27931 /**
27932 * Internal parser for private keys as specified in
27933 * {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.5.3|RFC4880bis-04 section 5.5.3}
27934 * @param {String} bytes - Input string to read the packet from
27935 */
27936 read(bytes) {
27937 // - A Public-Key or Public-Subkey packet, as described above.
27938 let i = this.readPublicKey(bytes);
27939
27940 // - One octet indicating string-to-key usage conventions. Zero
27941 // indicates that the secret-key data is not encrypted. 255 or 254
27942 // indicates that a string-to-key specifier is being given. Any
27943 // other value is a symmetric-key encryption algorithm identifier.
27944 this.s2k_usage = bytes[i++];
27945
27946 // - Only for a version 5 packet, a one-octet scalar octet count of
27947 // the next 4 optional fields.
27948 if (this.version === 5) {
27949 i++;
27950 }
27951
27952 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
27953 // one-octet symmetric encryption algorithm.
27954 if (this.s2k_usage === 255 || this.s2k_usage === 254 || this.s2k_usage === 253) {
27955 this.symmetric = bytes[i++];
27956 this.symmetric = enums.read(enums.symmetric, this.symmetric);
27957
27958 // - [Optional] If string-to-key usage octet was 253, a one-octet
27959 // AEAD algorithm.
27960 if (this.s2k_usage === 253) {
27961 this.aead = bytes[i++];
27962 this.aead = enums.read(enums.aead, this.aead);
27963 }
27964
27965 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
27966 // string-to-key specifier. The length of the string-to-key
27967 // specifier is implied by its type, as described above.
27968 this.s2k = new S2K();
27969 i += this.s2k.read(bytes.subarray(i, bytes.length));
27970
27971 if (this.s2k.type === 'gnu-dummy') {
27972 return;
27973 }
27974 } else if (this.s2k_usage) {
27975 this.symmetric = this.s2k_usage;
27976 this.symmetric = enums.read(enums.symmetric, this.symmetric);
27977 }
27978
27979 // - [Optional] If secret data is encrypted (string-to-key usage octet
27980 // not zero), an Initial Vector (IV) of the same length as the
27981 // cipher's block size.
27982 if (this.s2k_usage) {
27983 this.iv = bytes.subarray(
27984 i,
27985 i + mod.cipher[this.symmetric].blockSize
27986 );
27987
27988 i += this.iv.length;
27989 }
27990
27991 // - Only for a version 5 packet, a four-octet scalar octet count for
27992 // the following key material.
27993 if (this.version === 5) {
27994 i += 4;
27995 }
27996
27997 // - Plain or encrypted multiprecision integers comprising the secret
27998 // key data. These algorithm-specific fields are as described
27999 // below.
28000 this.keyMaterial = bytes.subarray(i);
28001 this.isEncrypted = !!this.s2k_usage;
28002
28003 if (!this.isEncrypted) {
28004 const cleartext = this.keyMaterial.subarray(0, -2);
28005 if (!util.equalsUint8Array(util.writeChecksum(cleartext), this.keyMaterial.subarray(-2))) {
28006 throw new Error('Key checksum mismatch');
28007 }
28008 try {
28009 const algo = enums.write(enums.publicKey, this.algorithm);
28010 const { privateParams } = mod.parsePrivateKeyParams(algo, cleartext, this.publicParams);
28011 this.privateParams = privateParams;
28012 } catch (err) {
28013 throw new Error('Error reading MPIs');
28014 }
28015 }
28016 }
28017
28018 /**
28019 * Creates an OpenPGP key packet for the given key.
28020 * @returns {Uint8Array} A string of bytes containing the secret key OpenPGP packet.
28021 */
28022 write() {
28023 const arr = [this.writePublicKey()];
28024
28025 arr.push(new Uint8Array([this.s2k_usage]));
28026
28027 const optionalFieldsArr = [];
28028 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
28029 // one- octet symmetric encryption algorithm.
28030 if (this.s2k_usage === 255 || this.s2k_usage === 254 || this.s2k_usage === 253) {
28031 optionalFieldsArr.push(enums.write(enums.symmetric, this.symmetric));
28032
28033 // - [Optional] If string-to-key usage octet was 253, a one-octet
28034 // AEAD algorithm.
28035 if (this.s2k_usage === 253) {
28036 optionalFieldsArr.push(enums.write(enums.aead, this.aead));
28037 }
28038
28039 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
28040 // string-to-key specifier. The length of the string-to-key
28041 // specifier is implied by its type, as described above.
28042 optionalFieldsArr.push(...this.s2k.write());
28043 }
28044
28045 // - [Optional] If secret data is encrypted (string-to-key usage octet
28046 // not zero), an Initial Vector (IV) of the same length as the
28047 // cipher's block size.
28048 if (this.s2k_usage && this.s2k.type !== 'gnu-dummy') {
28049 optionalFieldsArr.push(...this.iv);
28050 }
28051
28052 if (this.version === 5) {
28053 arr.push(new Uint8Array([optionalFieldsArr.length]));
28054 }
28055 arr.push(new Uint8Array(optionalFieldsArr));
28056
28057 if (!this.isDummy()) {
28058 if (!this.s2k_usage) {
28059 const algo = enums.write(enums.publicKey, this.algorithm);
28060 const cleartextParams = mod.serializeParams(algo, this.privateParams);
28061 this.keyMaterial = util.concatUint8Array([
28062 cleartextParams,
28063 util.writeChecksum(cleartextParams)
28064 ]);
28065 }
28066
28067 if (this.version === 5) {
28068 arr.push(util.writeNumber(this.keyMaterial.length, 4));
28069 }
28070 arr.push(this.keyMaterial);
28071 }
28072
28073 return util.concatUint8Array(arr);
28074 }
28075
28076 /**
28077 * Check whether secret-key data is available in decrypted form.
28078 * Returns false for gnu-dummy keys and null for public keys.
28079 * @returns {Boolean|null}
28080 */
28081 isDecrypted() {
28082 return this.isEncrypted === false;
28083 }
28084
28085 /**
28086 * Check whether this is a gnu-dummy key
28087 * @returns {Boolean}
28088 */
28089 isDummy() {
28090 return !!(this.s2k && this.s2k.type === 'gnu-dummy');
28091 }
28092
28093 /**
28094 * Remove private key material, converting the key to a dummy one.
28095 * The resulting key cannot be used for signing/decrypting but can still verify signatures.
28096 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28097 */
28098 makeDummy(config = defaultConfig) {
28099 if (this.isDummy()) {
28100 return;
28101 }
28102 if (this.isDecrypted()) {
28103 this.clearPrivateParams();
28104 }
28105 this.isEncrypted = null;
28106 this.keyMaterial = null;
28107 this.s2k = new S2K(config);
28108 this.s2k.algorithm = 0;
28109 this.s2k.c = 0;
28110 this.s2k.type = 'gnu-dummy';
28111 this.s2k_usage = 254;
28112 this.symmetric = 'aes256';
28113 }
28114
28115 /**
28116 * Encrypt the payload. By default, we use aes256 and iterated, salted string
28117 * to key specifier. If the key is in a decrypted state (isEncrypted === false)
28118 * and the passphrase is empty or undefined, the key will be set as not encrypted.
28119 * This can be used to remove passphrase protection after calling decrypt().
28120 * @param {String} passphrase
28121 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28122 * @throws {Error} if encryption was not successful
28123 * @async
28124 */
28125 async encrypt(passphrase, config = defaultConfig) {
28126 if (this.isDummy()) {
28127 return;
28128 }
28129
28130 if (!this.isDecrypted()) {
28131 throw new Error('Key packet is already encrypted');
28132 }
28133
28134 if (this.isDecrypted() && !passphrase) {
28135 this.s2k_usage = 0;
28136 return;
28137 } else if (!passphrase) {
28138 throw new Error('The key must be decrypted before removing passphrase protection.');
28139 }
28140
28141 this.s2k = new S2K(config);
28142 this.s2k.salt = await mod.random.getRandomBytes(8);
28143 const algo = enums.write(enums.publicKey, this.algorithm);
28144 const cleartext = mod.serializeParams(algo, this.privateParams);
28145 this.symmetric = 'aes256';
28146 const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
28147 const blockLen = mod.cipher[this.symmetric].blockSize;
28148 this.iv = await mod.random.getRandomBytes(blockLen);
28149
28150 if (config.aeadProtect) {
28151 this.s2k_usage = 253;
28152 this.aead = 'eax';
28153 const mode = mod[this.aead];
28154 const modeInstance = await mode(this.symmetric, key);
28155 this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array());
28156 } else {
28157 this.s2k_usage = 254;
28158 this.keyMaterial = await mod.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
28159 cleartext,
28160 await mod.hash.sha1(cleartext, config)
28161 ]), this.iv, config);
28162 }
28163 }
28164
28165 /**
28166 * Decrypts the private key params which are needed to use the key.
28167 * {@link SecretKeyPacket.isDecrypted} should be false, as
28168 * otherwise calls to this function will throw an error.
28169 * @param {String} passphrase - The passphrase for this private key as string
28170 * @throws {Error} if decryption was not successful
28171 * @async
28172 */
28173 async decrypt(passphrase) {
28174 if (this.isDummy()) {
28175 return false;
28176 }
28177
28178 if (this.isDecrypted()) {
28179 throw new Error('Key packet is already decrypted.');
28180 }
28181
28182 let key;
28183 if (this.s2k_usage === 254 || this.s2k_usage === 253) {
28184 key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
28185 } else if (this.s2k_usage === 255) {
28186 throw new Error('Encrypted private key is authenticated using an insecure two-byte hash');
28187 } else {
28188 throw new Error('Private key is encrypted using an insecure S2K function: unsalted MD5');
28189 }
28190
28191 let cleartext;
28192 if (this.s2k_usage === 253) {
28193 const mode = mod[this.aead];
28194 try {
28195 const modeInstance = await mode(this.symmetric, key);
28196 cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array());
28197 } catch (err) {
28198 if (err.message === 'Authentication tag mismatch') {
28199 throw new Error('Incorrect key passphrase: ' + err.message);
28200 }
28201 throw err;
28202 }
28203 } else {
28204 const cleartextWithHash = await mod.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv);
28205
28206 cleartext = cleartextWithHash.subarray(0, -20);
28207 const hash = await mod.hash.sha1(cleartext);
28208
28209 if (!util.equalsUint8Array(hash, cleartextWithHash.subarray(-20))) {
28210 throw new Error('Incorrect key passphrase');
28211 }
28212 }
28213
28214 try {
28215 const algo = enums.write(enums.publicKey, this.algorithm);
28216 const { privateParams } = mod.parsePrivateKeyParams(algo, cleartext, this.publicParams);
28217 this.privateParams = privateParams;
28218 } catch (err) {
28219 throw new Error('Error reading MPIs');
28220 }
28221 this.isEncrypted = false;
28222 this.keyMaterial = null;
28223 this.s2k_usage = 0;
28224 }
28225
28226 /**
28227 * Checks that the key parameters are consistent
28228 * @throws {Error} if validation was not successful
28229 * @async
28230 */
28231 async validate() {
28232 if (this.isDummy()) {
28233 return;
28234 }
28235
28236 if (!this.isDecrypted()) {
28237 throw new Error('Key is not decrypted');
28238 }
28239
28240 const algo = enums.write(enums.publicKey, this.algorithm);
28241
28242 let validParams;
28243 try {
28244 // this can throw if some parameters are undefined
28245 validParams = await mod.validateParams(algo, this.publicParams, this.privateParams);
28246 } catch (_) {
28247 validParams = false;
28248 }
28249 if (!validParams) {
28250 throw new Error('Key is invalid');
28251 }
28252 }
28253
28254 async generate(bits, curve) {
28255 const algo = enums.write(enums.publicKey, this.algorithm);
28256 const { privateParams, publicParams } = await mod.generateParams(algo, bits, curve);
28257 this.privateParams = privateParams;
28258 this.publicParams = publicParams;
28259 this.isEncrypted = false;
28260 }
28261
28262 /**
28263 * Clear private key parameters
28264 */
28265 clearPrivateParams() {
28266 if (this.isDummy()) {
28267 return;
28268 }
28269
28270 Object.keys(this.privateParams).forEach(name => {
28271 const param = this.privateParams[name];
28272 param.fill(0);
28273 delete this.privateParams[name];
28274 });
28275 this.privateParams = null;
28276 this.isEncrypted = true;
28277 }
28278}
28279
28280async function produceEncryptionKey(s2k, passphrase, algorithm) {
28281 return s2k.produce_key(
28282 passphrase,
28283 mod.cipher[algorithm].keySize
28284 );
28285}
28286
28287var emailAddresses = createCommonjsModule(function (module) {
28288// email-addresses.js - RFC 5322 email address parser
28289// v 3.1.0
28290//
28291// http://tools.ietf.org/html/rfc5322
28292//
28293// This library does not validate email addresses.
28294// emailAddresses attempts to parse addresses using the (fairly liberal)
28295// grammar specified in RFC 5322.
28296//
28297// email-addresses returns {
28298// ast: <an abstract syntax tree based on rfc5322>,
28299// addresses: [{
28300// node: <node in ast for this address>,
28301// name: <display-name>,
28302// address: <addr-spec>,
28303// local: <local-part>,
28304// domain: <domain>
28305// }, ...]
28306// }
28307//
28308// emailAddresses.parseOneAddress and emailAddresses.parseAddressList
28309// work as you might expect. Try it out.
28310//
28311// Many thanks to Dominic Sayers and his documentation on the is_email function,
28312// http://code.google.com/p/isemail/ , which helped greatly in writing this parser.
28313
28314(function (global) {
28315
28316function parse5322(opts) {
28317
28318 // tokenizing functions
28319
28320 function inStr() { return pos < len; }
28321 function curTok() { return parseString[pos]; }
28322 function getPos() { return pos; }
28323 function setPos(i) { pos = i; }
28324 function nextTok() { pos += 1; }
28325 function initialize() {
28326 pos = 0;
28327 len = parseString.length;
28328 }
28329
28330 // parser helper functions
28331
28332 function o(name, value) {
28333 return {
28334 name: name,
28335 tokens: value || "",
28336 semantic: value || "",
28337 children: []
28338 };
28339 }
28340
28341 function wrap(name, ast) {
28342 var n;
28343 if (ast === null) { return null; }
28344 n = o(name);
28345 n.tokens = ast.tokens;
28346 n.semantic = ast.semantic;
28347 n.children.push(ast);
28348 return n;
28349 }
28350
28351 function add(parent, child) {
28352 if (child !== null) {
28353 parent.tokens += child.tokens;
28354 parent.semantic += child.semantic;
28355 }
28356 parent.children.push(child);
28357 return parent;
28358 }
28359
28360 function compareToken(fxnCompare) {
28361 var tok;
28362 if (!inStr()) { return null; }
28363 tok = curTok();
28364 if (fxnCompare(tok)) {
28365 nextTok();
28366 return o('token', tok);
28367 }
28368 return null;
28369 }
28370
28371 function literal(lit) {
28372 return function literalFunc() {
28373 return wrap('literal', compareToken(function (tok) {
28374 return tok === lit;
28375 }));
28376 };
28377 }
28378
28379 function and() {
28380 var args = arguments;
28381 return function andFunc() {
28382 var i, s, result, start;
28383 start = getPos();
28384 s = o('and');
28385 for (i = 0; i < args.length; i += 1) {
28386 result = args[i]();
28387 if (result === null) {
28388 setPos(start);
28389 return null;
28390 }
28391 add(s, result);
28392 }
28393 return s;
28394 };
28395 }
28396
28397 function or() {
28398 var args = arguments;
28399 return function orFunc() {
28400 var i, result, start;
28401 start = getPos();
28402 for (i = 0; i < args.length; i += 1) {
28403 result = args[i]();
28404 if (result !== null) {
28405 return result;
28406 }
28407 setPos(start);
28408 }
28409 return null;
28410 };
28411 }
28412
28413 function opt(prod) {
28414 return function optFunc() {
28415 var result, start;
28416 start = getPos();
28417 result = prod();
28418 if (result !== null) {
28419 return result;
28420 }
28421 else {
28422 setPos(start);
28423 return o('opt');
28424 }
28425 };
28426 }
28427
28428 function invis(prod) {
28429 return function invisFunc() {
28430 var result = prod();
28431 if (result !== null) {
28432 result.semantic = "";
28433 }
28434 return result;
28435 };
28436 }
28437
28438 function colwsp(prod) {
28439 return function collapseSemanticWhitespace() {
28440 var result = prod();
28441 if (result !== null && result.semantic.length > 0) {
28442 result.semantic = " ";
28443 }
28444 return result;
28445 };
28446 }
28447
28448 function star(prod, minimum) {
28449 return function starFunc() {
28450 var s, result, count, start, min;
28451 start = getPos();
28452 s = o('star');
28453 count = 0;
28454 min = minimum === undefined ? 0 : minimum;
28455 while ((result = prod()) !== null) {
28456 count = count + 1;
28457 add(s, result);
28458 }
28459 if (count >= min) {
28460 return s;
28461 }
28462 else {
28463 setPos(start);
28464 return null;
28465 }
28466 };
28467 }
28468
28469 // One expects names to get normalized like this:
28470 // " First Last " -> "First Last"
28471 // "First Last" -> "First Last"
28472 // "First Last" -> "First Last"
28473 function collapseWhitespace(s) {
28474 return s.replace(/([ \t]|\r\n)+/g, ' ').replace(/^\s*/, '').replace(/\s*$/, '');
28475 }
28476
28477 // UTF-8 pseudo-production (RFC 6532)
28478 // RFC 6532 extends RFC 5322 productions to include UTF-8
28479 // using the following productions:
28480 // UTF8-non-ascii = UTF8-2 / UTF8-3 / UTF8-4
28481 // UTF8-2 = <Defined in Section 4 of RFC3629>
28482 // UTF8-3 = <Defined in Section 4 of RFC3629>
28483 // UTF8-4 = <Defined in Section 4 of RFC3629>
28484 //
28485 // For reference, the extended RFC 5322 productions are:
28486 // VCHAR =/ UTF8-non-ascii
28487 // ctext =/ UTF8-non-ascii
28488 // atext =/ UTF8-non-ascii
28489 // qtext =/ UTF8-non-ascii
28490 // dtext =/ UTF8-non-ascii
28491 function isUTF8NonAscii(tok) {
28492 // In JavaScript, we just deal directly with Unicode code points,
28493 // so we aren't checking individual bytes for UTF-8 encoding.
28494 // Just check that the character is non-ascii.
28495 return tok.charCodeAt(0) >= 128;
28496 }
28497
28498
28499 // common productions (RFC 5234)
28500 // http://tools.ietf.org/html/rfc5234
28501 // B.1. Core Rules
28502
28503 // CR = %x0D
28504 // ; carriage return
28505 function cr() { return wrap('cr', literal('\r')()); }
28506
28507 // CRLF = CR LF
28508 // ; Internet standard newline
28509 function crlf() { return wrap('crlf', and(cr, lf)()); }
28510
28511 // DQUOTE = %x22
28512 // ; " (Double Quote)
28513 function dquote() { return wrap('dquote', literal('"')()); }
28514
28515 // HTAB = %x09
28516 // ; horizontal tab
28517 function htab() { return wrap('htab', literal('\t')()); }
28518
28519 // LF = %x0A
28520 // ; linefeed
28521 function lf() { return wrap('lf', literal('\n')()); }
28522
28523 // SP = %x20
28524 function sp() { return wrap('sp', literal(' ')()); }
28525
28526 // VCHAR = %x21-7E
28527 // ; visible (printing) characters
28528 function vchar() {
28529 return wrap('vchar', compareToken(function vcharFunc(tok) {
28530 var code = tok.charCodeAt(0);
28531 var accept = (0x21 <= code && code <= 0x7E);
28532 if (opts.rfc6532) {
28533 accept = accept || isUTF8NonAscii(tok);
28534 }
28535 return accept;
28536 }));
28537 }
28538
28539 // WSP = SP / HTAB
28540 // ; white space
28541 function wsp() { return wrap('wsp', or(sp, htab)()); }
28542
28543
28544 // email productions (RFC 5322)
28545 // http://tools.ietf.org/html/rfc5322
28546 // 3.2.1. Quoted characters
28547
28548 // quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
28549 function quotedPair() {
28550 var qp = wrap('quoted-pair',
28551 or(
28552 and(literal('\\'), or(vchar, wsp)),
28553 obsQP
28554 )());
28555 if (qp === null) { return null; }
28556 // a quoted pair will be two characters, and the "\" character
28557 // should be semantically "invisible" (RFC 5322 3.2.1)
28558 qp.semantic = qp.semantic[1];
28559 return qp;
28560 }
28561
28562 // 3.2.2. Folding White Space and Comments
28563
28564 // FWS = ([*WSP CRLF] 1*WSP) / obs-FWS
28565 function fws() {
28566 return wrap('fws', or(
28567 obsFws,
28568 and(
28569 opt(and(
28570 star(wsp),
28571 invis(crlf)
28572 )),
28573 star(wsp, 1)
28574 )
28575 )());
28576 }
28577
28578 // ctext = %d33-39 / ; Printable US-ASCII
28579 // %d42-91 / ; characters not including
28580 // %d93-126 / ; "(", ")", or "\"
28581 // obs-ctext
28582 function ctext() {
28583 return wrap('ctext', or(
28584 function ctextFunc1() {
28585 return compareToken(function ctextFunc2(tok) {
28586 var code = tok.charCodeAt(0);
28587 var accept =
28588 (33 <= code && code <= 39) ||
28589 (42 <= code && code <= 91) ||
28590 (93 <= code && code <= 126);
28591 if (opts.rfc6532) {
28592 accept = accept || isUTF8NonAscii(tok);
28593 }
28594 return accept;
28595 });
28596 },
28597 obsCtext
28598 )());
28599 }
28600
28601 // ccontent = ctext / quoted-pair / comment
28602 function ccontent() {
28603 return wrap('ccontent', or(ctext, quotedPair, comment)());
28604 }
28605
28606 // comment = "(" *([FWS] ccontent) [FWS] ")"
28607 function comment() {
28608 return wrap('comment', and(
28609 literal('('),
28610 star(and(opt(fws), ccontent)),
28611 opt(fws),
28612 literal(')')
28613 )());
28614 }
28615
28616 // CFWS = (1*([FWS] comment) [FWS]) / FWS
28617 function cfws() {
28618 return wrap('cfws', or(
28619 and(
28620 star(
28621 and(opt(fws), comment),
28622 1
28623 ),
28624 opt(fws)
28625 ),
28626 fws
28627 )());
28628 }
28629
28630 // 3.2.3. Atom
28631
28632 //atext = ALPHA / DIGIT / ; Printable US-ASCII
28633 // "!" / "#" / ; characters not including
28634 // "$" / "%" / ; specials. Used for atoms.
28635 // "&" / "'" /
28636 // "*" / "+" /
28637 // "-" / "/" /
28638 // "=" / "?" /
28639 // "^" / "_" /
28640 // "`" / "{" /
28641 // "|" / "}" /
28642 // "~"
28643 function atext() {
28644 return wrap('atext', compareToken(function atextFunc(tok) {
28645 var accept =
28646 ('a' <= tok && tok <= 'z') ||
28647 ('A' <= tok && tok <= 'Z') ||
28648 ('0' <= tok && tok <= '9') ||
28649 (['!', '#', '$', '%', '&', '\'', '*', '+', '-', '/',
28650 '=', '?', '^', '_', '`', '{', '|', '}', '~'].indexOf(tok) >= 0);
28651 if (opts.rfc6532) {
28652 accept = accept || isUTF8NonAscii(tok);
28653 }
28654 return accept;
28655 }));
28656 }
28657
28658 // atom = [CFWS] 1*atext [CFWS]
28659 function atom() {
28660 return wrap('atom', and(colwsp(opt(cfws)), star(atext, 1), colwsp(opt(cfws)))());
28661 }
28662
28663 // dot-atom-text = 1*atext *("." 1*atext)
28664 function dotAtomText() {
28665 var s, maybeText;
28666 s = wrap('dot-atom-text', star(atext, 1)());
28667 if (s === null) { return s; }
28668 maybeText = star(and(literal('.'), star(atext, 1)))();
28669 if (maybeText !== null) {
28670 add(s, maybeText);
28671 }
28672 return s;
28673 }
28674
28675 // dot-atom = [CFWS] dot-atom-text [CFWS]
28676 function dotAtom() {
28677 return wrap('dot-atom', and(invis(opt(cfws)), dotAtomText, invis(opt(cfws)))());
28678 }
28679
28680 // 3.2.4. Quoted Strings
28681
28682 // qtext = %d33 / ; Printable US-ASCII
28683 // %d35-91 / ; characters not including
28684 // %d93-126 / ; "\" or the quote character
28685 // obs-qtext
28686 function qtext() {
28687 return wrap('qtext', or(
28688 function qtextFunc1() {
28689 return compareToken(function qtextFunc2(tok) {
28690 var code = tok.charCodeAt(0);
28691 var accept =
28692 (33 === code) ||
28693 (35 <= code && code <= 91) ||
28694 (93 <= code && code <= 126);
28695 if (opts.rfc6532) {
28696 accept = accept || isUTF8NonAscii(tok);
28697 }
28698 return accept;
28699 });
28700 },
28701 obsQtext
28702 )());
28703 }
28704
28705 // qcontent = qtext / quoted-pair
28706 function qcontent() {
28707 return wrap('qcontent', or(qtext, quotedPair)());
28708 }
28709
28710 // quoted-string = [CFWS]
28711 // DQUOTE *([FWS] qcontent) [FWS] DQUOTE
28712 // [CFWS]
28713 function quotedString() {
28714 return wrap('quoted-string', and(
28715 invis(opt(cfws)),
28716 invis(dquote), star(and(opt(colwsp(fws)), qcontent)), opt(invis(fws)), invis(dquote),
28717 invis(opt(cfws))
28718 )());
28719 }
28720
28721 // 3.2.5 Miscellaneous Tokens
28722
28723 // word = atom / quoted-string
28724 function word() {
28725 return wrap('word', or(atom, quotedString)());
28726 }
28727
28728 // phrase = 1*word / obs-phrase
28729 function phrase() {
28730 return wrap('phrase', or(obsPhrase, star(word, 1))());
28731 }
28732
28733 // 3.4. Address Specification
28734 // address = mailbox / group
28735 function address() {
28736 return wrap('address', or(mailbox, group)());
28737 }
28738
28739 // mailbox = name-addr / addr-spec
28740 function mailbox() {
28741 return wrap('mailbox', or(nameAddr, addrSpec)());
28742 }
28743
28744 // name-addr = [display-name] angle-addr
28745 function nameAddr() {
28746 return wrap('name-addr', and(opt(displayName), angleAddr)());
28747 }
28748
28749 // angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
28750 // obs-angle-addr
28751 function angleAddr() {
28752 return wrap('angle-addr', or(
28753 and(
28754 invis(opt(cfws)),
28755 literal('<'),
28756 addrSpec,
28757 literal('>'),
28758 invis(opt(cfws))
28759 ),
28760 obsAngleAddr
28761 )());
28762 }
28763
28764 // group = display-name ":" [group-list] ";" [CFWS]
28765 function group() {
28766 return wrap('group', and(
28767 displayName,
28768 literal(':'),
28769 opt(groupList),
28770 literal(';'),
28771 invis(opt(cfws))
28772 )());
28773 }
28774
28775 // display-name = phrase
28776 function displayName() {
28777 return wrap('display-name', function phraseFixedSemantic() {
28778 var result = phrase();
28779 if (result !== null) {
28780 result.semantic = collapseWhitespace(result.semantic);
28781 }
28782 return result;
28783 }());
28784 }
28785
28786 // mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
28787 function mailboxList() {
28788 return wrap('mailbox-list', or(
28789 and(
28790 mailbox,
28791 star(and(literal(','), mailbox))
28792 ),
28793 obsMboxList
28794 )());
28795 }
28796
28797 // address-list = (address *("," address)) / obs-addr-list
28798 function addressList() {
28799 return wrap('address-list', or(
28800 and(
28801 address,
28802 star(and(literal(','), address))
28803 ),
28804 obsAddrList
28805 )());
28806 }
28807
28808 // group-list = mailbox-list / CFWS / obs-group-list
28809 function groupList() {
28810 return wrap('group-list', or(
28811 mailboxList,
28812 invis(cfws),
28813 obsGroupList
28814 )());
28815 }
28816
28817 // 3.4.1 Addr-Spec Specification
28818
28819 // local-part = dot-atom / quoted-string / obs-local-part
28820 function localPart() {
28821 // note: quoted-string, dotAtom are proper subsets of obs-local-part
28822 // so we really just have to look for obsLocalPart, if we don't care about the exact parse tree
28823 return wrap('local-part', or(obsLocalPart, dotAtom, quotedString)());
28824 }
28825
28826 // dtext = %d33-90 / ; Printable US-ASCII
28827 // %d94-126 / ; characters not including
28828 // obs-dtext ; "[", "]", or "\"
28829 function dtext() {
28830 return wrap('dtext', or(
28831 function dtextFunc1() {
28832 return compareToken(function dtextFunc2(tok) {
28833 var code = tok.charCodeAt(0);
28834 var accept =
28835 (33 <= code && code <= 90) ||
28836 (94 <= code && code <= 126);
28837 if (opts.rfc6532) {
28838 accept = accept || isUTF8NonAscii(tok);
28839 }
28840 return accept;
28841 });
28842 },
28843 obsDtext
28844 )()
28845 );
28846 }
28847
28848 // domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
28849 function domainLiteral() {
28850 return wrap('domain-literal', and(
28851 invis(opt(cfws)),
28852 literal('['),
28853 star(and(opt(fws), dtext)),
28854 opt(fws),
28855 literal(']'),
28856 invis(opt(cfws))
28857 )());
28858 }
28859
28860 // domain = dot-atom / domain-literal / obs-domain
28861 function domain() {
28862 return wrap('domain', function domainCheckTLD() {
28863 var result = or(obsDomain, dotAtom, domainLiteral)();
28864 if (opts.rejectTLD) {
28865 if (result && result.semantic && result.semantic.indexOf('.') < 0) {
28866 return null;
28867 }
28868 }
28869 // strip all whitespace from domains
28870 if (result) {
28871 result.semantic = result.semantic.replace(/\s+/g, '');
28872 }
28873 return result;
28874 }());
28875 }
28876
28877 // addr-spec = local-part "@" domain
28878 function addrSpec() {
28879 return wrap('addr-spec', and(
28880 localPart, literal('@'), domain
28881 )());
28882 }
28883
28884 // 3.6.2 Originator Fields
28885 // Below we only parse the field body, not the name of the field
28886 // like "From:", "Sender:", or "Reply-To:". Other libraries that
28887 // parse email headers can parse those and defer to these productions
28888 // for the "RFC 5322" part.
28889
28890 // RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
28891 // from = "From:" (mailbox-list / address-list) CRLF
28892 function fromSpec() {
28893 return wrap('from', or(
28894 mailboxList,
28895 addressList
28896 )());
28897 }
28898
28899 // RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
28900 // sender = "Sender:" (mailbox / address) CRLF
28901 function senderSpec() {
28902 return wrap('sender', or(
28903 mailbox,
28904 address
28905 )());
28906 }
28907
28908 // RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
28909 // reply-to = "Reply-To:" address-list CRLF
28910 function replyToSpec() {
28911 return wrap('reply-to', addressList());
28912 }
28913
28914 // 4.1. Miscellaneous Obsolete Tokens
28915
28916 // obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
28917 // %d11 / ; characters that do not
28918 // %d12 / ; include the carriage
28919 // %d14-31 / ; return, line feed, and
28920 // %d127 ; white space characters
28921 function obsNoWsCtl() {
28922 return opts.strict ? null : wrap('obs-NO-WS-CTL', compareToken(function (tok) {
28923 var code = tok.charCodeAt(0);
28924 return ((1 <= code && code <= 8) ||
28925 (11 === code || 12 === code) ||
28926 (14 <= code && code <= 31) ||
28927 (127 === code));
28928 }));
28929 }
28930
28931 // obs-ctext = obs-NO-WS-CTL
28932 function obsCtext() { return opts.strict ? null : wrap('obs-ctext', obsNoWsCtl()); }
28933
28934 // obs-qtext = obs-NO-WS-CTL
28935 function obsQtext() { return opts.strict ? null : wrap('obs-qtext', obsNoWsCtl()); }
28936
28937 // obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
28938 function obsQP() {
28939 return opts.strict ? null : wrap('obs-qp', and(
28940 literal('\\'),
28941 or(literal('\0'), obsNoWsCtl, lf, cr)
28942 )());
28943 }
28944
28945 // obs-phrase = word *(word / "." / CFWS)
28946 function obsPhrase() {
28947 if (opts.strict ) return null;
28948 return opts.atInDisplayName ? wrap('obs-phrase', and(
28949 word,
28950 star(or(word, literal('.'), literal('@'), colwsp(cfws)))
28951 )()) :
28952 wrap('obs-phrase', and(
28953 word,
28954 star(or(word, literal('.'), colwsp(cfws)))
28955 )());
28956 }
28957
28958 // 4.2. Obsolete Folding White Space
28959
28960 // NOTE: read the errata http://www.rfc-editor.org/errata_search.php?rfc=5322&eid=1908
28961 // obs-FWS = 1*([CRLF] WSP)
28962 function obsFws() {
28963 return opts.strict ? null : wrap('obs-FWS', star(
28964 and(invis(opt(crlf)), wsp),
28965 1
28966 )());
28967 }
28968
28969 // 4.4. Obsolete Addressing
28970
28971 // obs-angle-addr = [CFWS] "<" obs-route addr-spec ">" [CFWS]
28972 function obsAngleAddr() {
28973 return opts.strict ? null : wrap('obs-angle-addr', and(
28974 invis(opt(cfws)),
28975 literal('<'),
28976 obsRoute,
28977 addrSpec,
28978 literal('>'),
28979 invis(opt(cfws))
28980 )());
28981 }
28982
28983 // obs-route = obs-domain-list ":"
28984 function obsRoute() {
28985 return opts.strict ? null : wrap('obs-route', and(
28986 obsDomainList,
28987 literal(':')
28988 )());
28989 }
28990
28991 // obs-domain-list = *(CFWS / ",") "@" domain
28992 // *("," [CFWS] ["@" domain])
28993 function obsDomainList() {
28994 return opts.strict ? null : wrap('obs-domain-list', and(
28995 star(or(invis(cfws), literal(','))),
28996 literal('@'),
28997 domain,
28998 star(and(
28999 literal(','),
29000 invis(opt(cfws)),
29001 opt(and(literal('@'), domain))
29002 ))
29003 )());
29004 }
29005
29006 // obs-mbox-list = *([CFWS] ",") mailbox *("," [mailbox / CFWS])
29007 function obsMboxList() {
29008 return opts.strict ? null : wrap('obs-mbox-list', and(
29009 star(and(
29010 invis(opt(cfws)),
29011 literal(',')
29012 )),
29013 mailbox,
29014 star(and(
29015 literal(','),
29016 opt(and(
29017 mailbox,
29018 invis(cfws)
29019 ))
29020 ))
29021 )());
29022 }
29023
29024 // obs-addr-list = *([CFWS] ",") address *("," [address / CFWS])
29025 function obsAddrList() {
29026 return opts.strict ? null : wrap('obs-addr-list', and(
29027 star(and(
29028 invis(opt(cfws)),
29029 literal(',')
29030 )),
29031 address,
29032 star(and(
29033 literal(','),
29034 opt(and(
29035 address,
29036 invis(cfws)
29037 ))
29038 ))
29039 )());
29040 }
29041
29042 // obs-group-list = 1*([CFWS] ",") [CFWS]
29043 function obsGroupList() {
29044 return opts.strict ? null : wrap('obs-group-list', and(
29045 star(and(
29046 invis(opt(cfws)),
29047 literal(',')
29048 ), 1),
29049 invis(opt(cfws))
29050 )());
29051 }
29052
29053 // obs-local-part = word *("." word)
29054 function obsLocalPart() {
29055 return opts.strict ? null : wrap('obs-local-part', and(word, star(and(literal('.'), word)))());
29056 }
29057
29058 // obs-domain = atom *("." atom)
29059 function obsDomain() {
29060 return opts.strict ? null : wrap('obs-domain', and(atom, star(and(literal('.'), atom)))());
29061 }
29062
29063 // obs-dtext = obs-NO-WS-CTL / quoted-pair
29064 function obsDtext() {
29065 return opts.strict ? null : wrap('obs-dtext', or(obsNoWsCtl, quotedPair)());
29066 }
29067
29068 /////////////////////////////////////////////////////
29069
29070 // ast analysis
29071
29072 function findNode(name, root) {
29073 var i, stack, node;
29074 if (root === null || root === undefined) { return null; }
29075 stack = [root];
29076 while (stack.length > 0) {
29077 node = stack.pop();
29078 if (node.name === name) {
29079 return node;
29080 }
29081 for (i = node.children.length - 1; i >= 0; i -= 1) {
29082 stack.push(node.children[i]);
29083 }
29084 }
29085 return null;
29086 }
29087
29088 function findAllNodes(name, root) {
29089 var i, stack, node, result;
29090 if (root === null || root === undefined) { return null; }
29091 stack = [root];
29092 result = [];
29093 while (stack.length > 0) {
29094 node = stack.pop();
29095 if (node.name === name) {
29096 result.push(node);
29097 }
29098 for (i = node.children.length - 1; i >= 0; i -= 1) {
29099 stack.push(node.children[i]);
29100 }
29101 }
29102 return result;
29103 }
29104
29105 function findAllNodesNoChildren(names, root) {
29106 var i, stack, node, result, namesLookup;
29107 if (root === null || root === undefined) { return null; }
29108 stack = [root];
29109 result = [];
29110 namesLookup = {};
29111 for (i = 0; i < names.length; i += 1) {
29112 namesLookup[names[i]] = true;
29113 }
29114
29115 while (stack.length > 0) {
29116 node = stack.pop();
29117 if (node.name in namesLookup) {
29118 result.push(node);
29119 // don't look at children (hence findAllNodesNoChildren)
29120 } else {
29121 for (i = node.children.length - 1; i >= 0; i -= 1) {
29122 stack.push(node.children[i]);
29123 }
29124 }
29125 }
29126 return result;
29127 }
29128
29129 function giveResult(ast) {
29130 var addresses, groupsAndMailboxes, i, groupOrMailbox, result;
29131 if (ast === null) {
29132 return null;
29133 }
29134 addresses = [];
29135
29136 // An address is a 'group' (i.e. a list of mailboxes) or a 'mailbox'.
29137 groupsAndMailboxes = findAllNodesNoChildren(['group', 'mailbox'], ast);
29138 for (i = 0; i < groupsAndMailboxes.length; i += 1) {
29139 groupOrMailbox = groupsAndMailboxes[i];
29140 if (groupOrMailbox.name === 'group') {
29141 addresses.push(giveResultGroup(groupOrMailbox));
29142 } else if (groupOrMailbox.name === 'mailbox') {
29143 addresses.push(giveResultMailbox(groupOrMailbox));
29144 }
29145 }
29146
29147 result = {
29148 ast: ast,
29149 addresses: addresses,
29150 };
29151 if (opts.simple) {
29152 result = simplifyResult(result);
29153 }
29154 if (opts.oneResult) {
29155 return oneResult(result);
29156 }
29157 if (opts.simple) {
29158 return result && result.addresses;
29159 } else {
29160 return result;
29161 }
29162 }
29163
29164 function giveResultGroup(group) {
29165 var i;
29166 var groupName = findNode('display-name', group);
29167 var groupResultMailboxes = [];
29168 var mailboxes = findAllNodesNoChildren(['mailbox'], group);
29169 for (i = 0; i < mailboxes.length; i += 1) {
29170 groupResultMailboxes.push(giveResultMailbox(mailboxes[i]));
29171 }
29172 return {
29173 node: group,
29174 parts: {
29175 name: groupName,
29176 },
29177 type: group.name, // 'group'
29178 name: grabSemantic(groupName),
29179 addresses: groupResultMailboxes,
29180 };
29181 }
29182
29183 function giveResultMailbox(mailbox) {
29184 var name = findNode('display-name', mailbox);
29185 var aspec = findNode('addr-spec', mailbox);
29186 var cfws = findAllNodes('cfws', mailbox);
29187 var comments = findAllNodesNoChildren(['comment'], mailbox);
29188
29189
29190 var local = findNode('local-part', aspec);
29191 var domain = findNode('domain', aspec);
29192 return {
29193 node: mailbox,
29194 parts: {
29195 name: name,
29196 address: aspec,
29197 local: local,
29198 domain: domain,
29199 comments: cfws
29200 },
29201 type: mailbox.name, // 'mailbox'
29202 name: grabSemantic(name),
29203 address: grabSemantic(aspec),
29204 local: grabSemantic(local),
29205 domain: grabSemantic(domain),
29206 comments: concatComments(comments),
29207 groupName: grabSemantic(mailbox.groupName),
29208 };
29209 }
29210
29211 function grabSemantic(n) {
29212 return n !== null && n !== undefined ? n.semantic : null;
29213 }
29214
29215 function simplifyResult(result) {
29216 var i;
29217 if (result && result.addresses) {
29218 for (i = 0; i < result.addresses.length; i += 1) {
29219 delete result.addresses[i].node;
29220 }
29221 }
29222 return result;
29223 }
29224
29225 function concatComments(comments) {
29226 var result = '';
29227 if (comments) {
29228 for (var i = 0; i < comments.length; i += 1) {
29229 result += grabSemantic(comments[i]);
29230 }
29231 }
29232 return result;
29233 }
29234
29235 function oneResult(result) {
29236 if (!result) { return null; }
29237 if (!opts.partial && result.addresses.length > 1) { return null; }
29238 return result.addresses && result.addresses[0];
29239 }
29240
29241 /////////////////////////////////////////////////////
29242
29243 var parseString, pos, len, parsed, startProduction;
29244
29245 opts = handleOpts(opts, {});
29246 if (opts === null) { return null; }
29247
29248 parseString = opts.input;
29249
29250 startProduction = {
29251 'address': address,
29252 'address-list': addressList,
29253 'angle-addr': angleAddr,
29254 'from': fromSpec,
29255 'group': group,
29256 'mailbox': mailbox,
29257 'mailbox-list': mailboxList,
29258 'reply-to': replyToSpec,
29259 'sender': senderSpec,
29260 }[opts.startAt] || addressList;
29261
29262 if (!opts.strict) {
29263 initialize();
29264 opts.strict = true;
29265 parsed = startProduction(parseString);
29266 if (opts.partial || !inStr()) {
29267 return giveResult(parsed);
29268 }
29269 opts.strict = false;
29270 }
29271
29272 initialize();
29273 parsed = startProduction(parseString);
29274 if (!opts.partial && inStr()) { return null; }
29275 return giveResult(parsed);
29276}
29277
29278function parseOneAddressSimple(opts) {
29279 return parse5322(handleOpts(opts, {
29280 oneResult: true,
29281 rfc6532: true,
29282 simple: true,
29283 startAt: 'address-list',
29284 }));
29285}
29286
29287function parseAddressListSimple(opts) {
29288 return parse5322(handleOpts(opts, {
29289 rfc6532: true,
29290 simple: true,
29291 startAt: 'address-list',
29292 }));
29293}
29294
29295function parseFromSimple(opts) {
29296 return parse5322(handleOpts(opts, {
29297 rfc6532: true,
29298 simple: true,
29299 startAt: 'from',
29300 }));
29301}
29302
29303function parseSenderSimple(opts) {
29304 return parse5322(handleOpts(opts, {
29305 oneResult: true,
29306 rfc6532: true,
29307 simple: true,
29308 startAt: 'sender',
29309 }));
29310}
29311
29312function parseReplyToSimple(opts) {
29313 return parse5322(handleOpts(opts, {
29314 rfc6532: true,
29315 simple: true,
29316 startAt: 'reply-to',
29317 }));
29318}
29319
29320function handleOpts(opts, defs) {
29321 function isString(str) {
29322 return Object.prototype.toString.call(str) === '[object String]';
29323 }
29324
29325 function isObject(o) {
29326 return o === Object(o);
29327 }
29328
29329 function isNullUndef(o) {
29330 return o === null || o === undefined;
29331 }
29332
29333 var defaults, o;
29334
29335 if (isString(opts)) {
29336 opts = { input: opts };
29337 } else if (!isObject(opts)) {
29338 return null;
29339 }
29340
29341 if (!isString(opts.input)) { return null; }
29342 if (!defs) { return null; }
29343
29344 defaults = {
29345 oneResult: false,
29346 partial: false,
29347 rejectTLD: false,
29348 rfc6532: false,
29349 simple: false,
29350 startAt: 'address-list',
29351 strict: false,
29352 atInDisplayName: false
29353 };
29354
29355 for (o in defaults) {
29356 if (isNullUndef(opts[o])) {
29357 opts[o] = !isNullUndef(defs[o]) ? defs[o] : defaults[o];
29358 }
29359 }
29360 return opts;
29361}
29362
29363parse5322.parseOneAddress = parseOneAddressSimple;
29364parse5322.parseAddressList = parseAddressListSimple;
29365parse5322.parseFrom = parseFromSimple;
29366parse5322.parseSender = parseSenderSimple;
29367parse5322.parseReplyTo = parseReplyToSimple;
29368
29369{
29370 module.exports = parse5322;
29371}
29372
29373}());
29374});
29375
29376// GPG4Browsers - An OpenPGP implementation in javascript
29377
29378/**
29379 * Implementation of the User ID Packet (Tag 13)
29380 *
29381 * A User ID packet consists of UTF-8 text that is intended to represent
29382 * the name and email address of the key holder. By convention, it
29383 * includes an RFC 2822 [RFC2822] mail name-addr, but there are no
29384 * restrictions on its content. The packet length in the header
29385 * specifies the length of the User ID.
29386 */
29387class UserIDPacket {
29388 constructor() {
29389 this.tag = enums.packet.userID;
29390 /** A string containing the user id. Usually in the form
29391 * John Doe <john@example.com>
29392 * @type {String}
29393 */
29394 this.userid = '';
29395
29396 this.name = '';
29397 this.email = '';
29398 this.comment = '';
29399 }
29400
29401 /**
29402 * Create UserIDPacket instance from object
29403 * @param {Object} userId - Object specifying userId name, email and comment
29404 * @returns {UserIDPacket}
29405 * @static
29406 */
29407 static fromObject(userId) {
29408 if (util.isString(userId) ||
29409 (userId.name && !util.isString(userId.name)) ||
29410 (userId.email && !util.isEmailAddress(userId.email)) ||
29411 (userId.comment && !util.isString(userId.comment))) {
29412 throw new Error('Invalid user ID format');
29413 }
29414 const packet = new UserIDPacket();
29415 Object.assign(packet, userId);
29416 const components = [];
29417 if (packet.name) components.push(packet.name);
29418 if (packet.comment) components.push(`(${packet.comment})`);
29419 if (packet.email) components.push(`<${packet.email}>`);
29420 packet.userid = components.join(' ');
29421 return packet;
29422 }
29423
29424 /**
29425 * Parsing function for a user id packet (tag 13).
29426 * @param {Uint8Array} input - Payload of a tag 13 packet
29427 */
29428 read(bytes, config = defaultConfig) {
29429 const userid = util.decodeUtf8(bytes);
29430 if (userid.length > config.maxUseridLength) {
29431 throw new Error('User ID string is too long');
29432 }
29433 try {
29434 const { name, address: email, comments } = emailAddresses.parseOneAddress({ input: userid, atInDisplayName: true });
29435 this.comment = comments.replace(/^\(|\)$/g, '');
29436 this.name = name;
29437 this.email = email;
29438 } catch (e) {}
29439 this.userid = userid;
29440 }
29441
29442 /**
29443 * Creates a binary representation of the user id packet
29444 * @returns {Uint8Array} Binary representation.
29445 */
29446 write() {
29447 return util.encodeUtf8(this.userid);
29448 }
29449}
29450
29451// GPG4Browsers - An OpenPGP implementation in javascript
29452
29453/**
29454 * A Secret-Subkey packet (tag 7) is the subkey analog of the Secret
29455 * Key packet and has exactly the same format.
29456 * @extends SecretKeyPacket
29457 */
29458class SecretSubkeyPacket extends SecretKeyPacket {
29459 /**
29460 * @param {Date} [date] - Creation date
29461 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29462 */
29463 constructor(date = new Date(), config = defaultConfig) {
29464 super(date, config);
29465 this.tag = enums.packet.secretSubkey;
29466 }
29467}
29468
29469/* eslint class-methods-use-this: ["error", { "exceptMethods": ["read"] }] */
29470
29471/**
29472 * Implementation of the Trust Packet (Tag 12)
29473 *
29474 * {@link https://tools.ietf.org/html/rfc4880#section-5.10|RFC4880 5.10}:
29475 * The Trust packet is used only within keyrings and is not normally
29476 * exported. Trust packets contain data that record the user's
29477 * specifications of which key holders are trustworthy introducers,
29478 * along with other information that implementing software uses for
29479 * trust information. The format of Trust packets is defined by a given
29480 * implementation.
29481 *
29482 * Trust packets SHOULD NOT be emitted to output streams that are
29483 * transferred to other users, and they SHOULD be ignored on any input
29484 * other than local keyring files.
29485 */
29486class TrustPacket {
29487 constructor() {
29488 this.tag = enums.packet.trust;
29489 }
29490
29491 /**
29492 * Parsing function for a trust packet (tag 12).
29493 * Currently not implemented as we ignore trust packets
29494 * @param {String} byptes - Payload of a tag 12 packet
29495 */
29496 read() {} // TODO
29497}
29498
29499/**
29500 * @fileoverview Exports all OpenPGP packet types
29501 * @module packet/all_packets
29502 * @private
29503 */
29504
29505/**
29506 * Allocate a new packet
29507 * @function newPacketFromTag
29508 * @param {String} tag - Property name from {@link module:enums.packet}
29509 * @returns {Object} New packet object with type based on tag.
29510 */
29511function newPacketFromTag(tag, allowedPackets) {
29512 const className = packetClassFromTagName(tag);
29513 if (!allowedPackets[className]) {
29514 throw new Error('Packet not allowed in this context: ' + className);
29515 }
29516 return new allowedPackets[className]();
29517}
29518
29519/**
29520 * Convert tag name to class name
29521 * @param {String} tag - Property name from {@link module:enums.packet}
29522 * @returns {String}
29523 * @private
29524 */
29525function packetClassFromTagName(tag) {
29526 return tag.substr(0, 1).toUpperCase() + tag.substr(1) + 'Packet';
29527}
29528
29529/**
29530 * This class represents a list of openpgp packets.
29531 * Take care when iterating over it - the packets themselves
29532 * are stored as numerical indices.
29533 * @extends Array
29534 */
29535class PacketList extends Array {
29536 /**
29537 * Reads a stream of binary data and interprets it as a list of packets.
29538 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - A Uint8Array of bytes.
29539 */
29540 async read(bytes, allowedPackets, streaming, config = defaultConfig) {
29541 this.stream = stream.transformPair(bytes, async (readable, writable) => {
29542 const writer = stream.getWriter(writable);
29543 try {
29544 while (true) {
29545 await writer.ready;
29546 const done = await readPackets(readable, streaming, async parsed => {
29547 try {
29548 const tag = enums.read(enums.packet, parsed.tag);
29549 const packet = newPacketFromTag(tag, allowedPackets);
29550 packet.packets = new PacketList();
29551 packet.fromStream = util.isStream(parsed.packet);
29552 await packet.read(parsed.packet, config, streaming);
29553 await writer.write(packet);
29554 } catch (e) {
29555 if (!config.tolerant || supportsStreaming(parsed.tag)) {
29556 // The packets that support streaming are the ones that contain
29557 // message data. Those are also the ones we want to be more strict
29558 // about and throw on parse errors for.
29559 await writer.abort(e);
29560 }
29561 util.printDebugError(e);
29562 }
29563 });
29564 if (done) {
29565 await writer.ready;
29566 await writer.close();
29567 return;
29568 }
29569 }
29570 } catch (e) {
29571 await writer.abort(e);
29572 }
29573 });
29574
29575 // Wait until first few packets have been read
29576 const reader = stream.getReader(this.stream);
29577 while (true) {
29578 const { done, value } = await reader.read();
29579 if (!done) {
29580 this.push(value);
29581 } else {
29582 this.stream = null;
29583 }
29584 if (done || supportsStreaming(value.tag)) {
29585 break;
29586 }
29587 }
29588 reader.releaseLock();
29589 }
29590
29591 /**
29592 * Creates a binary representation of openpgp objects contained within the
29593 * class instance.
29594 * @returns {Uint8Array} A Uint8Array containing valid openpgp packets.
29595 */
29596 write() {
29597 const arr = [];
29598
29599 for (let i = 0; i < this.length; i++) {
29600 const packetbytes = this[i].write();
29601 if (util.isStream(packetbytes) && supportsStreaming(this[i].tag)) {
29602 let buffer = [];
29603 let bufferLength = 0;
29604 const minLength = 512;
29605 arr.push(writeTag(this[i].tag));
29606 arr.push(stream.transform(packetbytes, value => {
29607 buffer.push(value);
29608 bufferLength += value.length;
29609 if (bufferLength >= minLength) {
29610 const powerOf2 = Math.min(Math.log(bufferLength) / Math.LN2 | 0, 30);
29611 const chunkSize = 2 ** powerOf2;
29612 const bufferConcat = util.concat([writePartialLength(powerOf2)].concat(buffer));
29613 buffer = [bufferConcat.subarray(1 + chunkSize)];
29614 bufferLength = buffer[0].length;
29615 return bufferConcat.subarray(0, 1 + chunkSize);
29616 }
29617 }, () => util.concat([writeSimpleLength(bufferLength)].concat(buffer))));
29618 } else {
29619 if (util.isStream(packetbytes)) {
29620 let length = 0;
29621 arr.push(stream.transform(stream.clone(packetbytes), value => {
29622 length += value.length;
29623 }, () => writeHeader(this[i].tag, length)));
29624 } else {
29625 arr.push(writeHeader(this[i].tag, packetbytes.length));
29626 }
29627 arr.push(packetbytes);
29628 }
29629 }
29630
29631 return util.concat(arr);
29632 }
29633
29634 /**
29635 * Adds a packet to the list. This is the only supported method of doing so;
29636 * writing to packetlist[i] directly will result in an error.
29637 * @param {Object} packet - Packet to push
29638 */
29639 push(packet) {
29640 if (!packet) {
29641 return;
29642 }
29643
29644 packet.packets = packet.packets || new PacketList();
29645
29646 super.push(packet);
29647 }
29648
29649 /**
29650 * Creates a new PacketList with all packets from the given types
29651 */
29652 filterByTag(...args) {
29653 const filtered = new PacketList();
29654
29655 const handle = tag => packetType => tag === packetType;
29656
29657 for (let i = 0; i < this.length; i++) {
29658 if (args.some(handle(this[i].tag))) {
29659 filtered.push(this[i]);
29660 }
29661 }
29662
29663 return filtered;
29664 }
29665
29666 /**
29667 * Traverses packet tree and returns first matching packet
29668 * @param {module:enums.packet} type - The packet type
29669 * @returns {Packet|undefined}
29670 */
29671 findPacket(type) {
29672 return this.find(packet => packet.tag === type);
29673 }
29674
29675 /**
29676 * Returns array of found indices by tag
29677 */
29678 indexOfTag(...args) {
29679 const tagIndex = [];
29680 const that = this;
29681
29682 const handle = tag => packetType => tag === packetType;
29683
29684 for (let i = 0; i < this.length; i++) {
29685 if (args.some(handle(that[i].tag))) {
29686 tagIndex.push(i);
29687 }
29688 }
29689 return tagIndex;
29690 }
29691
29692 /**
29693 * Concatenates packetlist or array of packets
29694 */
29695 concat(packetlist) {
29696 if (packetlist) {
29697 for (let i = 0; i < packetlist.length; i++) {
29698 this.push(packetlist[i]);
29699 }
29700 }
29701 return this;
29702 }
29703}
29704
29705// GPG4Browsers - An OpenPGP implementation in javascript
29706
29707/**
29708 * Class that represents an OpenPGP signature.
29709 */
29710class Signature {
29711 /**
29712 * @param {PacketList} packetlist - The signature packets
29713 */
29714 constructor(packetlist) {
29715 this.packets = packetlist || new PacketList();
29716 }
29717
29718 /**
29719 * Returns binary encoded signature
29720 * @returns {ReadableStream<Uint8Array>} Binary signature.
29721 */
29722 write() {
29723 return this.packets.write();
29724 }
29725
29726 /**
29727 * Returns ASCII armored text of signature
29728 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29729 * @returns {ReadableStream<String>} ASCII armor.
29730 */
29731 armor(config = defaultConfig) {
29732 return armor(enums.armor.signature, this.write(), undefined, undefined, undefined, config);
29733 }
29734}
29735
29736/**
29737 * reads an (optionally armored) OpenPGP signature and returns a signature object
29738 * @param {Object} options
29739 * @param {String | ReadableStream<String>} [options.armoredSignature] - Armored signature to be parsed
29740 * @param {Uint8Array | ReadableStream<Uint8Array>} [options.binarySignature] - Binary signature to be parsed
29741 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
29742 * @returns {Signature} New signature object.
29743 * @async
29744 * @static
29745 */
29746async function readSignature({ armoredSignature, binarySignature, config }) {
29747 config = { ...defaultConfig, ...config };
29748 let input = armoredSignature || binarySignature;
29749 if (!input) {
29750 throw new Error('readSignature: must pass options object containing `armoredSignature` or `binarySignature`');
29751 }
29752 if (armoredSignature) {
29753 const { type, data } = await unarmor(input, config);
29754 if (type !== enums.armor.signature) {
29755 throw new Error('Armored text not of type signature');
29756 }
29757 input = data;
29758 }
29759 const packetlist = new PacketList();
29760 await packetlist.read(input, { SignaturePacket }, undefined, config);
29761 return new Signature(packetlist);
29762}
29763
29764/**
29765 * @fileoverview Provides helpers methods for key module
29766 * @module key/helper
29767 * @private
29768 */
29769
29770const allowedKeyPackets = {
29771 PublicKeyPacket,
29772 PublicSubkeyPacket,
29773 SecretKeyPacket,
29774 SecretSubkeyPacket,
29775 UserIDPacket,
29776 UserAttributePacket,
29777 SignaturePacket
29778};
29779
29780async function generateSecretSubkey(options, config) {
29781 const secretSubkeyPacket = new SecretSubkeyPacket(options.date, config);
29782 secretSubkeyPacket.packets = null;
29783 secretSubkeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm);
29784 await secretSubkeyPacket.generate(options.rsaBits, options.curve);
29785 return secretSubkeyPacket;
29786}
29787
29788async function generateSecretKey(options, config) {
29789 const secretKeyPacket = new SecretKeyPacket(options.date, config);
29790 secretKeyPacket.packets = null;
29791 secretKeyPacket.algorithm = enums.read(enums.publicKey, options.algorithm);
29792 await secretKeyPacket.generate(options.rsaBits, options.curve, options.config);
29793 return secretKeyPacket;
29794}
29795
29796/**
29797 * Returns the valid and non-expired signature that has the latest creation date, while ignoring signatures created in the future.
29798 * @param {Array<SignaturePacket>} signatures - List of signatures
29799 * @param {Date} date - Use the given date instead of the current time
29800 * @param {Object} config - full configuration
29801 * @returns {SignaturePacket} The latest valid signature.
29802 * @async
29803 */
29804async function getLatestValidSignature(signatures, primaryKey, signatureType, dataToVerify, date = new Date(), config) {
29805 let signature;
29806 let exception;
29807 for (let i = signatures.length - 1; i >= 0; i--) {
29808 try {
29809 if (
29810 (!signature || signatures[i].created >= signature.created) &&
29811 // check binding signature is not expired (ie, check for V4 expiration time)
29812 !signatures[i].isExpired(date)
29813 ) {
29814 // check binding signature is verified
29815 signatures[i].verified || await signatures[i].verify(primaryKey, signatureType, dataToVerify, undefined, undefined, config);
29816 signature = signatures[i];
29817 }
29818 } catch (e) {
29819 exception = e;
29820 }
29821 }
29822 if (!signature) {
29823 throw util.wrapError(
29824 `Could not find valid ${enums.read(enums.signature, signatureType)} signature in key ${primaryKey.getKeyId().toHex()}`
29825 .replace('certGeneric ', 'self-')
29826 .replace(/([a-z])([A-Z])/g, (_, $1, $2) => $1 + ' ' + $2.toLowerCase())
29827 , exception);
29828 }
29829 return signature;
29830}
29831
29832function isDataExpired(keyPacket, signature, date = new Date()) {
29833 const normDate = util.normalizeDate(date);
29834 if (normDate !== null) {
29835 const expirationTime = getExpirationTime(keyPacket, signature);
29836 return !(keyPacket.created <= normDate && normDate <= expirationTime) ||
29837 (signature && signature.isExpired(date));
29838 }
29839 return false;
29840}
29841
29842/**
29843 * Create Binding signature to the key according to the {@link https://tools.ietf.org/html/rfc4880#section-5.2.1}
29844 * @param {SecretSubkeyPacket} subkey - Subkey key packet
29845 * @param {SecretKeyPacket} primaryKey - Primary key packet
29846 * @param {Object} options
29847 * @param {Object} config - Full configuration
29848 */
29849async function createBindingSignature(subkey, primaryKey, options, config) {
29850 const dataToSign = {};
29851 dataToSign.key = primaryKey;
29852 dataToSign.bind = subkey;
29853 const subkeySignaturePacket = new SignaturePacket(options.date);
29854 subkeySignaturePacket.signatureType = enums.signature.subkeyBinding;
29855 subkeySignaturePacket.publicKeyAlgorithm = primaryKey.algorithm;
29856 subkeySignaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, subkey, undefined, undefined, config);
29857 if (options.sign) {
29858 subkeySignaturePacket.keyFlags = [enums.keyFlags.signData];
29859 subkeySignaturePacket.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
29860 signatureType: enums.signature.keyBinding
29861 }, options.date, undefined, undefined, undefined, config);
29862 } else {
29863 subkeySignaturePacket.keyFlags = [enums.keyFlags.encryptCommunication | enums.keyFlags.encryptStorage];
29864 }
29865 if (options.keyExpirationTime > 0) {
29866 subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime;
29867 subkeySignaturePacket.keyNeverExpires = false;
29868 }
29869 await subkeySignaturePacket.sign(primaryKey, dataToSign);
29870 return subkeySignaturePacket;
29871}
29872
29873/**
29874 * Returns the preferred signature hash algorithm of a key
29875 * @param {Key} [key] - The key to get preferences from
29876 * @param {SecretKeyPacket|SecretSubkeyPacket} keyPacket - key packet used for signing
29877 * @param {Date} [date] - Use the given date for verification instead of the current time
29878 * @param {Object} [userId] - User ID
29879 * @param {Object} config - full configuration
29880 * @returns {String}
29881 * @async
29882 */
29883async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userId = {}, config) {
29884 let hash_algo = config.preferHashAlgorithm;
29885 let pref_algo = hash_algo;
29886 if (key) {
29887 const primaryUser = await key.getPrimaryUser(date, userId, config);
29888 if (primaryUser.selfCertification.preferredHashAlgorithms) {
29889 [pref_algo] = primaryUser.selfCertification.preferredHashAlgorithms;
29890 hash_algo = mod.hash.getHashByteLength(hash_algo) <= mod.hash.getHashByteLength(pref_algo) ?
29891 pref_algo : hash_algo;
29892 }
29893 }
29894 switch (Object.getPrototypeOf(keyPacket)) {
29895 case SecretKeyPacket.prototype:
29896 case PublicKeyPacket.prototype:
29897 case SecretSubkeyPacket.prototype:
29898 case PublicSubkeyPacket.prototype:
29899 switch (keyPacket.algorithm) {
29900 case 'ecdh':
29901 case 'ecdsa':
29902 case 'eddsa':
29903 pref_algo = mod.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
29904 }
29905 }
29906 return mod.hash.getHashByteLength(hash_algo) <= mod.hash.getHashByteLength(pref_algo) ?
29907 pref_algo : hash_algo;
29908}
29909
29910/**
29911 * Returns the preferred symmetric/aead algorithm for a set of keys
29912 * @param {symmetric|aead} type - Type of preference to return
29913 * @param {Array<Key>} keys - Set of keys
29914 * @param {Date} [date] - Use the given date for verification instead of the current time
29915 * @param {Array} [userIds] - User IDs
29916 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29917 * @returns {module:enums.symmetric} Preferred symmetric algorithm.
29918 * @async
29919 */
29920async function getPreferredAlgo(type, keys, date = new Date(), userIds = [], config = defaultConfig) {
29921 const prefProperty = type === 'symmetric' ? 'preferredSymmetricAlgorithms' : 'preferredAeadAlgorithms';
29922 const defaultAlgo = type === 'symmetric' ? enums.symmetric.aes128 : enums.aead.eax;
29923 const prioMap = {};
29924 await Promise.all(keys.map(async function(key, i) {
29925 const primaryUser = await key.getPrimaryUser(date, userIds[i], config);
29926 if (!primaryUser.selfCertification[prefProperty]) {
29927 return defaultAlgo;
29928 }
29929 primaryUser.selfCertification[prefProperty].forEach(function(algo, index) {
29930 const entry = prioMap[algo] || (prioMap[algo] = { prio: 0, count: 0, algo: algo });
29931 entry.prio += 64 >> index;
29932 entry.count++;
29933 });
29934 }));
29935 let prefAlgo = { prio: 0, algo: defaultAlgo };
29936 Object.values(prioMap).forEach(({ prio, count, algo }) => {
29937 try {
29938 if (algo !== enums[type].plaintext &&
29939 algo !== enums[type].idea && // not implemented
29940 enums.read(enums[type], algo) && // known algorithm
29941 count === keys.length && // available for all keys
29942 prio > prefAlgo.prio) {
29943 prefAlgo = prioMap[algo];
29944 }
29945 } catch (e) {}
29946 });
29947 return prefAlgo.algo;
29948}
29949
29950/**
29951 * Create signature packet
29952 * @param {Object} dataToSign - Contains packets to be signed
29953 * @param {SecretKeyPacket|
29954 * SecretSubkeyPacket} signingKeyPacket secret key packet for signing
29955 * @param {Object} [signatureProperties] - Properties to write on the signature packet before signing
29956 * @param {Date} [date] - Override the creationtime of the signature
29957 * @param {Object} [userId] - User ID
29958 * @param {Object} [detached] - Whether to create a detached signature packet
29959 * @param {Boolean} [streaming] - Whether to process data as a stream
29960 * @param {Object} config - full configuration
29961 * @returns {SignaturePacket} Signature packet.
29962 * @async
29963 */
29964async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userId, detached = false, streaming = false, config) {
29965 if (signingKeyPacket.isDummy()) {
29966 throw new Error('Cannot sign with a gnu-dummy key.');
29967 }
29968 if (!signingKeyPacket.isDecrypted()) {
29969 throw new Error('Private key is not decrypted.');
29970 }
29971 const signaturePacket = new SignaturePacket(date);
29972 Object.assign(signaturePacket, signatureProperties);
29973 signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
29974 signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(privateKey, signingKeyPacket, date, userId, config);
29975 await signaturePacket.sign(signingKeyPacket, dataToSign, detached, streaming);
29976 return signaturePacket;
29977}
29978
29979/**
29980 * Merges signatures from source[attr] to dest[attr]
29981 * @param {Object} source
29982 * @param {Object} dest
29983 * @param {String} attr
29984 * @param {Function} checkFn - optional, signature only merged if true
29985 */
29986async function mergeSignatures(source, dest, attr, checkFn) {
29987 source = source[attr];
29988 if (source) {
29989 if (!dest[attr].length) {
29990 dest[attr] = source;
29991 } else {
29992 await Promise.all(source.map(async function(sourceSig) {
29993 if (!sourceSig.isExpired() && (!checkFn || await checkFn(sourceSig)) &&
29994 !dest[attr].some(function(destSig) {
29995 return util.equalsUint8Array(destSig.write_params(), sourceSig.write_params());
29996 })) {
29997 dest[attr].push(sourceSig);
29998 }
29999 }));
30000 }
30001 }
30002}
30003
30004/**
30005 * Checks if a given certificate or binding signature is revoked
30006 * @param {SecretKeyPacket|
30007 * PublicKeyPacket} primaryKey The primary key packet
30008 * @param {Object} dataToVerify - The data to check
30009 * @param {Array<SignaturePacket>} revocations - The revocation signatures to check
30010 * @param {SignaturePacket} signature - The certificate or signature to check
30011 * @param {PublicSubkeyPacket|
30012 * SecretSubkeyPacket|
30013 * PublicKeyPacket|
30014 * SecretKeyPacket} key, optional The key packet to check the signature
30015 * @param {Date} date - Use the given date instead of the current time
30016 * @param {Object} config - Full configuration
30017 * @returns {Boolean} True if the signature revokes the data.
30018 * @async
30019 */
30020async function isDataRevoked(primaryKey, signatureType, dataToVerify, revocations, signature, key, date = new Date(), config) {
30021 key = key || primaryKey;
30022 const normDate = util.normalizeDate(date);
30023 const revocationKeyIds = [];
30024 await Promise.all(revocations.map(async function(revocationSignature) {
30025 try {
30026 if (
30027 // Note: a third-party revocation signature could legitimately revoke a
30028 // self-signature if the signature has an authorized revocation key.
30029 // However, we don't support passing authorized revocation keys, nor
30030 // verifying such revocation signatures. Instead, we indicate an error
30031 // when parsing a key with an authorized revocation key, and ignore
30032 // third-party revocation signatures here. (It could also be revoking a
30033 // third-party key certification, which should only affect
30034 // `verifyAllCertifications`.)
30035 (!signature || revocationSignature.issuerKeyId.equals(signature.issuerKeyId)) &&
30036 !(config.revocationsExpire && revocationSignature.isExpired(normDate))
30037 ) {
30038 revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify, undefined, undefined, config);
30039
30040 // TODO get an identifier of the revoked object instead
30041 revocationKeyIds.push(revocationSignature.issuerKeyId);
30042 }
30043 } catch (e) {}
30044 }));
30045 // TODO further verify that this is the signature that should be revoked
30046 if (signature) {
30047 signature.revoked = revocationKeyIds.some(keyId => keyId.equals(signature.issuerKeyId)) ? true :
30048 signature.revoked || false;
30049 return signature.revoked;
30050 }
30051 return revocationKeyIds.length > 0;
30052}
30053
30054function getExpirationTime(keyPacket, signature) {
30055 let expirationTime;
30056 // check V4 expiration time
30057 if (signature.keyNeverExpires === false) {
30058 expirationTime = keyPacket.created.getTime() + signature.keyExpirationTime * 1000;
30059 }
30060 return expirationTime ? new Date(expirationTime) : Infinity;
30061}
30062
30063/**
30064 * Returns whether aead is supported by all keys in the set
30065 * @param {Array<Key>} keys - Set of keys
30066 * @param {Date} [date] - Use the given date for verification instead of the current time
30067 * @param {Array} [userIds] - User IDs
30068 * @param {Object} config - full configuration
30069 * @returns {Boolean}
30070 * @async
30071 */
30072async function isAeadSupported(keys, date = new Date(), userIds = [], config = defaultConfig) {
30073 let supported = true;
30074 // TODO replace when Promise.some or Promise.any are implemented
30075 await Promise.all(keys.map(async function(key, i) {
30076 const primaryUser = await key.getPrimaryUser(date, userIds[i], config);
30077 if (!primaryUser.selfCertification.features ||
30078 !(primaryUser.selfCertification.features[0] & enums.features.aead)) {
30079 supported = false;
30080 }
30081 }));
30082 return supported;
30083}
30084
30085function sanitizeKeyOptions(options, subkeyDefaults = {}) {
30086 options.type = options.type || subkeyDefaults.type;
30087 options.curve = options.curve || subkeyDefaults.curve;
30088 options.rsaBits = options.rsaBits || subkeyDefaults.rsaBits;
30089 options.keyExpirationTime = options.keyExpirationTime !== undefined ? options.keyExpirationTime : subkeyDefaults.keyExpirationTime;
30090 options.passphrase = util.isString(options.passphrase) ? options.passphrase : subkeyDefaults.passphrase;
30091 options.date = options.date || subkeyDefaults.date;
30092
30093 options.sign = options.sign || false;
30094
30095 switch (options.type) {
30096 case 'ecc':
30097 try {
30098 options.curve = enums.write(enums.curve, options.curve);
30099 } catch (e) {
30100 throw new Error('Invalid curve');
30101 }
30102 if (options.curve === enums.curve.ed25519 || options.curve === enums.curve.curve25519) {
30103 options.curve = options.sign ? enums.curve.ed25519 : enums.curve.curve25519;
30104 }
30105 if (options.sign) {
30106 options.algorithm = options.curve === enums.curve.ed25519 ? enums.publicKey.eddsa : enums.publicKey.ecdsa;
30107 } else {
30108 options.algorithm = enums.publicKey.ecdh;
30109 }
30110 break;
30111 case 'rsa':
30112 options.algorithm = enums.publicKey.rsaEncryptSign;
30113 break;
30114 default:
30115 throw new Error(`Unsupported key type ${options.type}`);
30116 }
30117 return options;
30118}
30119
30120function isValidSigningKeyPacket(keyPacket, signature) {
30121 if (!signature.verified || signature.revoked !== false) { // Sanity check
30122 throw new Error('Signature not verified');
30123 }
30124 return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsaEncrypt) &&
30125 keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.elgamal) &&
30126 keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdh) &&
30127 (!signature.keyFlags ||
30128 (signature.keyFlags[0] & enums.keyFlags.signData) !== 0);
30129}
30130
30131function isValidEncryptionKeyPacket(keyPacket, signature) {
30132 if (!signature.verified || signature.revoked !== false) { // Sanity check
30133 throw new Error('Signature not verified');
30134 }
30135 return keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.dsa) &&
30136 keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.rsaSign) &&
30137 keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.ecdsa) &&
30138 keyPacket.algorithm !== enums.read(enums.publicKey, enums.publicKey.eddsa) &&
30139 (!signature.keyFlags ||
30140 (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
30141 (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0);
30142}
30143
30144function isValidDecryptionKeyPacket(signature, config) {
30145 if (!signature.verified) { // Sanity check
30146 throw new Error('Signature not verified');
30147 }
30148
30149 if (config.allowInsecureDecryptionWithSigningKeys) {
30150 // This is only relevant for RSA keys, all other signing ciphers cannot decrypt
30151 return true;
30152 }
30153
30154 return !signature.keyFlags ||
30155 (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
30156 (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0;
30157}
30158
30159/**
30160 * @module key/User
30161 * @private
30162 */
30163
30164/**
30165 * Class that represents an user ID or attribute packet and the relevant signatures.
30166 */
30167class User {
30168 constructor(userPacket) {
30169 if (!(this instanceof User)) {
30170 return new User(userPacket);
30171 }
30172 this.userId = userPacket.tag === enums.packet.userID ? userPacket : null;
30173 this.userAttribute = userPacket.tag === enums.packet.userAttribute ? userPacket : null;
30174 this.selfCertifications = [];
30175 this.otherCertifications = [];
30176 this.revocationSignatures = [];
30177 }
30178
30179 /**
30180 * Transforms structured user data to packetlist
30181 * @returns {PacketList}
30182 */
30183 toPacketlist() {
30184 const packetlist = new PacketList();
30185 packetlist.push(this.userId || this.userAttribute);
30186 packetlist.concat(this.revocationSignatures);
30187 packetlist.concat(this.selfCertifications);
30188 packetlist.concat(this.otherCertifications);
30189 return packetlist;
30190 }
30191
30192 /**
30193 * Signs user
30194 * @param {SecretKeyPacket|
30195 * PublicKeyPacket} primaryKey The primary key packet
30196 * @param {Array<Key>} privateKeys - Decrypted private keys for signing
30197 * @param {Object} config - Full configuration
30198 * @returns {Key} New user with new certificate signatures.
30199 * @async
30200 */
30201 async sign(primaryKey, privateKeys, config) {
30202 const dataToSign = {
30203 userId: this.userId,
30204 userAttribute: this.userAttribute,
30205 key: primaryKey
30206 };
30207 const user = new User(dataToSign.userId || dataToSign.userAttribute);
30208 user.otherCertifications = await Promise.all(privateKeys.map(async function(privateKey) {
30209 if (privateKey.isPublic()) {
30210 throw new Error('Need private key for signing');
30211 }
30212 if (privateKey.hasSameFingerprintAs(primaryKey)) {
30213 throw new Error('Not implemented for self signing');
30214 }
30215 const signingKey = await privateKey.getSigningKey(undefined, undefined, undefined, config);
30216 return createSignaturePacket(dataToSign, privateKey, signingKey.keyPacket, {
30217 // Most OpenPGP implementations use generic certification (0x10)
30218 signatureType: enums.signature.certGeneric,
30219 keyFlags: [enums.keyFlags.certifyKeys | enums.keyFlags.signData]
30220 }, undefined, undefined, undefined, undefined, config);
30221 }));
30222 await user.update(this, primaryKey);
30223 return user;
30224 }
30225
30226 /**
30227 * Checks if a given certificate of the user is revoked
30228 * @param {SecretKeyPacket|
30229 * PublicKeyPacket} primaryKey The primary key packet
30230 * @param {SignaturePacket} certificate - The certificate to verify
30231 * @param {PublicSubkeyPacket|
30232 * SecretSubkeyPacket|
30233 * PublicKeyPacket|
30234 * SecretKeyPacket} key, optional The key to verify the signature
30235 * @param {Date} date - Use the given date instead of the current time
30236 * @param {Object} config - Full configuration
30237 * @returns {Boolean} True if the certificate is revoked.
30238 * @async
30239 */
30240 async isRevoked(primaryKey, certificate, key, date = new Date(), config) {
30241 return isDataRevoked(
30242 primaryKey, enums.signature.certRevocation, {
30243 key: primaryKey,
30244 userId: this.userId,
30245 userAttribute: this.userAttribute
30246 }, this.revocationSignatures, certificate, key, date, config
30247 );
30248 }
30249
30250 /**
30251 * Verifies the user certificate. Throws if the user certificate is invalid.
30252 * @param {SecretKeyPacket|
30253 * PublicKeyPacket} primaryKey The primary key packet
30254 * @param {SignaturePacket} certificate - A certificate of this user
30255 * @param {Array<Key>} keys - Array of keys to verify certificate signatures
30256 * @param {Date} date - Use the given date instead of the current time
30257 * @param {Object} config - Full configuration
30258 * @returns {true|null} Status of the certificate.
30259 * @async
30260 */
30261 async verifyCertificate(primaryKey, certificate, keys, date = new Date(), config) {
30262 const that = this;
30263 const keyid = certificate.issuerKeyId;
30264 const dataToVerify = {
30265 userId: this.userId,
30266 userAttribute: this.userAttribute,
30267 key: primaryKey
30268 };
30269 const results = await Promise.all(keys.map(async function(key) {
30270 if (!key.getKeyIds().some(id => id.equals(keyid))) {
30271 return null;
30272 }
30273 const signingKey = await key.getSigningKey(keyid, date, undefined, config);
30274 if (certificate.revoked || await that.isRevoked(primaryKey, certificate, signingKey.keyPacket, date, config)) {
30275 throw new Error('User certificate is revoked');
30276 }
30277 try {
30278 certificate.verified || await certificate.verify(signingKey.keyPacket, enums.signature.certGeneric, dataToVerify, undefined, undefined, config);
30279 } catch (e) {
30280 throw util.wrapError('User certificate is invalid', e);
30281 }
30282 if (certificate.isExpired(date)) {
30283 throw new Error('User certificate is expired');
30284 }
30285 return true;
30286 }));
30287 return results.find(result => result !== null) || null;
30288 }
30289
30290 /**
30291 * Verifies all user certificates
30292 * @param {SecretKeyPacket|
30293 * PublicKeyPacket} primaryKey The primary key packet
30294 * @param {Array<Key>} keys - Array of keys to verify certificate signatures
30295 * @param {Date} date - Use the given date instead of the current time
30296 * @param {Object} config - Full configuration
30297 * @returns {Promise<Array<{keyid: module:type/keyid~Keyid,
30298 * valid: Boolean}>>} List of signer's keyid and validity of signature
30299 * @async
30300 */
30301 async verifyAllCertifications(primaryKey, keys, date = new Date(), config) {
30302 const that = this;
30303 const certifications = this.selfCertifications.concat(this.otherCertifications);
30304 return Promise.all(certifications.map(async function(certification) {
30305 return {
30306 keyid: certification.issuerKeyId,
30307 valid: await that.verifyCertificate(primaryKey, certification, keys, date, config).catch(() => false)
30308 };
30309 }));
30310 }
30311
30312 /**
30313 * Verify User. Checks for existence of self signatures, revocation signatures
30314 * and validity of self signature.
30315 * @param {SecretKeyPacket|
30316 * PublicKeyPacket} primaryKey The primary key packet
30317 * @param {Date} date - Use the given date instead of the current time
30318 * @param {Object} config - Full configuration
30319 * @returns {true} Status of user.
30320 * @throws {Error} if there are no valid self signatures.
30321 * @async
30322 */
30323 async verify(primaryKey, date = new Date(), config) {
30324 if (!this.selfCertifications.length) {
30325 throw new Error('No self-certifications');
30326 }
30327 const that = this;
30328 const dataToVerify = {
30329 userId: this.userId,
30330 userAttribute: this.userAttribute,
30331 key: primaryKey
30332 };
30333 // TODO replace when Promise.some or Promise.any are implemented
30334 let exception;
30335 for (let i = this.selfCertifications.length - 1; i >= 0; i--) {
30336 try {
30337 const selfCertification = this.selfCertifications[i];
30338 if (selfCertification.revoked || await that.isRevoked(primaryKey, selfCertification, undefined, date, config)) {
30339 throw new Error('Self-certification is revoked');
30340 }
30341 try {
30342 selfCertification.verified || await selfCertification.verify(primaryKey, enums.signature.certGeneric, dataToVerify, undefined, undefined, config);
30343 } catch (e) {
30344 throw util.wrapError('Self-certification is invalid', e);
30345 }
30346 if (selfCertification.isExpired(date)) {
30347 throw new Error('Self-certification is expired');
30348 }
30349 return true;
30350 } catch (e) {
30351 exception = e;
30352 }
30353 }
30354 throw exception;
30355 }
30356
30357 /**
30358 * Update user with new components from specified user
30359 * @param {User} user - Source user to merge
30360 * @param {SecretKeyPacket|
30361 * SecretSubkeyPacket} primaryKey primary key used for validation
30362 * @param {Object} config - Full configuration
30363 * @returns {undefined}
30364 * @async
30365 */
30366 async update(user, primaryKey, config) {
30367 const dataToVerify = {
30368 userId: this.userId,
30369 userAttribute: this.userAttribute,
30370 key: primaryKey
30371 };
30372 // self signatures
30373 await mergeSignatures(user, this, 'selfCertifications', async function(srcSelfSig) {
30374 try {
30375 srcSelfSig.verified || await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, undefined, undefined, config);
30376 return true;
30377 } catch (e) {
30378 return false;
30379 }
30380 });
30381 // other signatures
30382 await mergeSignatures(user, this, 'otherCertifications');
30383 // revocation signatures
30384 await mergeSignatures(user, this, 'revocationSignatures', function(srcRevSig) {
30385 return isDataRevoked(primaryKey, enums.signature.certRevocation, dataToVerify, [srcRevSig], undefined, undefined, undefined, config);
30386 });
30387 }
30388}
30389
30390/**
30391 * @module key/SubKey
30392 * @private
30393 */
30394
30395/**
30396 * Class that represents a subkey packet and the relevant signatures.
30397 * @borrows PublicSubkeyPacket#getKeyId as SubKey#getKeyId
30398 * @borrows PublicSubkeyPacket#getFingerprint as SubKey#getFingerprint
30399 * @borrows PublicSubkeyPacket#hasSameFingerprintAs as SubKey#hasSameFingerprintAs
30400 * @borrows PublicSubkeyPacket#getAlgorithmInfo as SubKey#getAlgorithmInfo
30401 * @borrows PublicSubkeyPacket#getCreationTime as SubKey#getCreationTime
30402 * @borrows PublicSubkeyPacket#isDecrypted as SubKey#isDecrypted
30403 */
30404class SubKey {
30405 constructor(subKeyPacket) {
30406 if (!(this instanceof SubKey)) {
30407 return new SubKey(subKeyPacket);
30408 }
30409 this.keyPacket = subKeyPacket;
30410 this.bindingSignatures = [];
30411 this.revocationSignatures = [];
30412 }
30413
30414 /**
30415 * Transforms structured subkey data to packetlist
30416 * @returns {PacketList}
30417 */
30418 toPacketlist() {
30419 const packetlist = new PacketList();
30420 packetlist.push(this.keyPacket);
30421 packetlist.concat(this.revocationSignatures);
30422 packetlist.concat(this.bindingSignatures);
30423 return packetlist;
30424 }
30425
30426 /**
30427 * Checks if a binding signature of a subkey is revoked
30428 * @param {SecretKeyPacket|
30429 * PublicKeyPacket} primaryKey The primary key packet
30430 * @param {SignaturePacket} signature - The binding signature to verify
30431 * @param {PublicSubkeyPacket|
30432 * SecretSubkeyPacket|
30433 * PublicKeyPacket|
30434 * SecretKeyPacket} key, optional The key to verify the signature
30435 * @param {Date} date - Use the given date instead of the current time
30436 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30437 * @returns {Boolean} True if the binding signature is revoked.
30438 * @async
30439 */
30440 async isRevoked(primaryKey, signature, key, date = new Date(), config = defaultConfig) {
30441 return isDataRevoked(
30442 primaryKey, enums.signature.subkeyRevocation, {
30443 key: primaryKey,
30444 bind: this.keyPacket
30445 }, this.revocationSignatures, signature, key, date, config
30446 );
30447 }
30448
30449 /**
30450 * Verify subkey. Checks for revocation signatures, expiration time
30451 * and valid binding signature.
30452 * @param {SecretKeyPacket|
30453 * PublicKeyPacket} primaryKey The primary key packet
30454 * @param {Date} date - Use the given date instead of the current time
30455 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30456 * @returns {SignaturePacket}
30457 * @throws {Error} if the subkey is invalid.
30458 * @async
30459 */
30460 async verify(primaryKey, date = new Date(), config = defaultConfig) {
30461 const dataToVerify = { key: primaryKey, bind: this.keyPacket };
30462 // check subkey binding signatures
30463 const bindingSignature = await getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
30464 // check binding signature is not revoked
30465 if (bindingSignature.revoked || await this.isRevoked(primaryKey, bindingSignature, null, date, config)) {
30466 throw new Error('Subkey is revoked');
30467 }
30468 // check for expiration time
30469 if (isDataExpired(this.keyPacket, bindingSignature, date)) {
30470 throw new Error('Subkey is expired');
30471 }
30472 return bindingSignature;
30473 }
30474
30475 /**
30476 * Returns the expiration time of the subkey or Infinity if key does not expire
30477 * Returns null if the subkey is invalid.
30478 * @param {SecretKeyPacket|
30479 * PublicKeyPacket} primaryKey The primary key packet
30480 * @param {Date} date - Use the given date instead of the current time
30481 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30482 * @returns {Date | Infinity | null}
30483 * @async
30484 */
30485 async getExpirationTime(primaryKey, date = new Date(), config = defaultConfig) {
30486 const dataToVerify = { key: primaryKey, bind: this.keyPacket };
30487 let bindingSignature;
30488 try {
30489 bindingSignature = await getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
30490 } catch (e) {
30491 return null;
30492 }
30493 const keyExpiry = getExpirationTime(this.keyPacket, bindingSignature);
30494 const sigExpiry = bindingSignature.getExpirationTime();
30495 return keyExpiry < sigExpiry ? keyExpiry : sigExpiry;
30496 }
30497
30498 /**
30499 * Update subkey with new components from specified subkey
30500 * @param {SubKey} subKey - Source subkey to merge
30501 * @param {SecretKeyPacket|
30502 SecretSubkeyPacket} primaryKey primary key used for validation
30503 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30504 * @throws {Error} if update failed
30505 * @async
30506 */
30507 async update(subKey, primaryKey, config = defaultConfig) {
30508 if (!this.hasSameFingerprintAs(subKey)) {
30509 throw new Error('SubKey update method: fingerprints of subkeys not equal');
30510 }
30511 // key packet
30512 if (this.keyPacket.tag === enums.packet.publicSubkey &&
30513 subKey.keyPacket.tag === enums.packet.secretSubkey) {
30514 this.keyPacket = subKey.keyPacket;
30515 }
30516 // update missing binding signatures
30517 const that = this;
30518 const dataToVerify = { key: primaryKey, bind: that.keyPacket };
30519 await mergeSignatures(subKey, this, 'bindingSignatures', async function(srcBindSig) {
30520 for (let i = 0; i < that.bindingSignatures.length; i++) {
30521 if (that.bindingSignatures[i].issuerKeyId.equals(srcBindSig.issuerKeyId)) {
30522 if (srcBindSig.created > that.bindingSignatures[i].created) {
30523 that.bindingSignatures[i] = srcBindSig;
30524 }
30525 return false;
30526 }
30527 }
30528 try {
30529 srcBindSig.verified || await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, undefined, undefined, config);
30530 return true;
30531 } catch (e) {
30532 return false;
30533 }
30534 });
30535 // revocation signatures
30536 await mergeSignatures(subKey, this, 'revocationSignatures', function(srcRevSig) {
30537 return isDataRevoked(primaryKey, enums.signature.subkeyRevocation, dataToVerify, [srcRevSig], undefined, undefined, undefined, config);
30538 });
30539 }
30540
30541 /**
30542 * Revokes the subkey
30543 * @param {SecretKeyPacket} primaryKey - decrypted private primary key for revocation
30544 * @param {Object} reasonForRevocation - optional, object indicating the reason for revocation
30545 * @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
30546 * @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
30547 * @param {Date} date - optional, override the creationtime of the revocation signature
30548 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30549 * @returns {SubKey} New subkey with revocation signature.
30550 * @async
30551 */
30552 async revoke(
30553 primaryKey,
30554 {
30555 flag: reasonForRevocationFlag = enums.reasonForRevocation.noReason,
30556 string: reasonForRevocationString = ''
30557 } = {},
30558 date = new Date(),
30559 config = defaultConfig
30560 ) {
30561 const dataToSign = { key: primaryKey, bind: this.keyPacket };
30562 const subKey = new SubKey(this.keyPacket);
30563 subKey.revocationSignatures.push(await createSignaturePacket(dataToSign, null, primaryKey, {
30564 signatureType: enums.signature.subkeyRevocation,
30565 reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
30566 reasonForRevocationString
30567 }, date, undefined, undefined, undefined, config));
30568 await subKey.update(this, primaryKey);
30569 return subKey;
30570 }
30571
30572 hasSameFingerprintAs(other) {
30573 return this.keyPacket.hasSameFingerprintAs(other.keyPacket || other);
30574 }
30575}
30576
30577['getKeyId', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'isDecrypted'].forEach(name => {
30578 SubKey.prototype[name] =
30579 function() {
30580 return this.keyPacket[name]();
30581 };
30582});
30583
30584// GPG4Browsers - An OpenPGP implementation in javascript
30585
30586/**
30587 * Class that represents an OpenPGP key. Must contain a primary key.
30588 * Can contain additional subkeys, signatures, user ids, user attributes.
30589 * @borrows PublicKeyPacket#getKeyId as Key#getKeyId
30590 * @borrows PublicKeyPacket#getFingerprint as Key#getFingerprint
30591 * @borrows PublicKeyPacket#hasSameFingerprintAs as Key#hasSameFingerprintAs
30592 * @borrows PublicKeyPacket#getAlgorithmInfo as Key#getAlgorithmInfo
30593 * @borrows PublicKeyPacket#getCreationTime as Key#getCreationTime
30594 */
30595class Key {
30596 /**
30597 * @param {PacketList} packetlist - The packets that form this key
30598 */
30599 constructor(packetlist) {
30600 if (!(this instanceof Key)) {
30601 return new Key(packetlist);
30602 }
30603 // same data as in packetlist but in structured form
30604 this.keyPacket = null;
30605 this.revocationSignatures = [];
30606 this.directSignatures = [];
30607 this.users = [];
30608 this.subKeys = [];
30609 this.packetlist2structure(packetlist);
30610 if (!this.keyPacket) {
30611 throw new Error('Invalid key: need at least key packet');
30612 }
30613 }
30614
30615 get primaryKey() {
30616 return this.keyPacket;
30617 }
30618
30619 /**
30620 * Transforms packetlist to structured key data
30621 * @param {PacketList} packetlist - The packets that form a key
30622 */
30623 packetlist2structure(packetlist) {
30624 let user;
30625 let primaryKeyId;
30626 let subKey;
30627 for (let i = 0; i < packetlist.length; i++) {
30628 switch (packetlist[i].tag) {
30629 case enums.packet.publicKey:
30630 case enums.packet.secretKey:
30631 if (this.keyPacket) {
30632 throw new Error('Key block contains multiple keys');
30633 }
30634 this.keyPacket = packetlist[i];
30635 primaryKeyId = this.getKeyId();
30636 break;
30637 case enums.packet.userID:
30638 case enums.packet.userAttribute:
30639 user = new User(packetlist[i]);
30640 this.users.push(user);
30641 break;
30642 case enums.packet.publicSubkey:
30643 case enums.packet.secretSubkey:
30644 user = null;
30645 subKey = new SubKey(packetlist[i]);
30646 this.subKeys.push(subKey);
30647 break;
30648 case enums.packet.signature:
30649 switch (packetlist[i].signatureType) {
30650 case enums.signature.certGeneric:
30651 case enums.signature.certPersona:
30652 case enums.signature.certCasual:
30653 case enums.signature.certPositive:
30654 if (!user) {
30655 util.printDebug('Dropping certification signatures without preceding user packet');
30656 continue;
30657 }
30658 if (packetlist[i].issuerKeyId.equals(primaryKeyId)) {
30659 user.selfCertifications.push(packetlist[i]);
30660 } else {
30661 user.otherCertifications.push(packetlist[i]);
30662 }
30663 break;
30664 case enums.signature.certRevocation:
30665 if (user) {
30666 user.revocationSignatures.push(packetlist[i]);
30667 } else {
30668 this.directSignatures.push(packetlist[i]);
30669 }
30670 break;
30671 case enums.signature.key:
30672 this.directSignatures.push(packetlist[i]);
30673 break;
30674 case enums.signature.subkeyBinding:
30675 if (!subKey) {
30676 util.printDebug('Dropping subkey binding signature without preceding subkey packet');
30677 continue;
30678 }
30679 subKey.bindingSignatures.push(packetlist[i]);
30680 break;
30681 case enums.signature.keyRevocation:
30682 this.revocationSignatures.push(packetlist[i]);
30683 break;
30684 case enums.signature.subkeyRevocation:
30685 if (!subKey) {
30686 util.printDebug('Dropping subkey revocation signature without preceding subkey packet');
30687 continue;
30688 }
30689 subKey.revocationSignatures.push(packetlist[i]);
30690 break;
30691 }
30692 break;
30693 }
30694 }
30695 }
30696
30697 /**
30698 * Transforms structured key data to packetlist
30699 * @returns {PacketList} The packets that form a key.
30700 */
30701 toPacketlist() {
30702 const packetlist = new PacketList();
30703 packetlist.push(this.keyPacket);
30704 packetlist.concat(this.revocationSignatures);
30705 packetlist.concat(this.directSignatures);
30706 this.users.map(user => packetlist.concat(user.toPacketlist()));
30707 this.subKeys.map(subKey => packetlist.concat(subKey.toPacketlist()));
30708 return packetlist;
30709 }
30710
30711 /**
30712 * Clones the key object
30713 * @returns {Key} Shallow clone of the key.
30714 * @async
30715 */
30716 async clone() {
30717 return new Key(this.toPacketlist());
30718 }
30719
30720 /**
30721 * Returns an array containing all public or private subkeys matching keyId;
30722 * If keyId is not present, returns all subkeys.
30723 * @param {type/keyid} keyId
30724 * @returns {Array<SubKey>}
30725 */
30726 getSubkeys(keyId = null) {
30727 const subKeys = [];
30728 this.subKeys.forEach(subKey => {
30729 if (!keyId || subKey.getKeyId().equals(keyId, true)) {
30730 subKeys.push(subKey);
30731 }
30732 });
30733 return subKeys;
30734 }
30735
30736 /**
30737 * Returns an array containing all public or private keys matching keyId.
30738 * If keyId is not present, returns all keys starting with the primary key.
30739 * @param {type/keyid} keyId
30740 * @returns {Array<Key|SubKey>}
30741 */
30742 getKeys(keyId = null) {
30743 const keys = [];
30744 if (!keyId || this.getKeyId().equals(keyId, true)) {
30745 keys.push(this);
30746 }
30747 return keys.concat(this.getSubkeys(keyId));
30748 }
30749
30750 /**
30751 * Returns key IDs of all keys
30752 * @returns {Array<module:type/keyid~Keyid>}
30753 */
30754 getKeyIds() {
30755 return this.getKeys().map(key => key.getKeyId());
30756 }
30757
30758 /**
30759 * Returns userids
30760 * @returns {Array<string>} Array of userids.
30761 */
30762 getUserIds() {
30763 return this.users.map(user => {
30764 return user.userId ? user.userId.userid : null;
30765 }).filter(userid => userid !== null);
30766 }
30767
30768 /**
30769 * Returns true if this is a public key
30770 * @returns {Boolean}
30771 */
30772 isPublic() {
30773 return this.keyPacket.tag === enums.packet.publicKey;
30774 }
30775
30776 /**
30777 * Returns true if this is a private key
30778 * @returns {Boolean}
30779 */
30780 isPrivate() {
30781 return this.keyPacket.tag === enums.packet.secretKey;
30782 }
30783
30784 /**
30785 * Returns key as public key (shallow copy)
30786 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30787 * @returns {Key} New public Key.
30788 */
30789 toPublic() {
30790 const packetlist = new PacketList();
30791 const keyPackets = this.toPacketlist();
30792 let bytes;
30793 let pubKeyPacket;
30794 let pubSubkeyPacket;
30795 for (let i = 0; i < keyPackets.length; i++) {
30796 switch (keyPackets[i].tag) {
30797 case enums.packet.secretKey:
30798 bytes = keyPackets[i].writePublicKey();
30799 pubKeyPacket = new PublicKeyPacket();
30800 pubKeyPacket.read(bytes);
30801 packetlist.push(pubKeyPacket);
30802 break;
30803 case enums.packet.secretSubkey:
30804 bytes = keyPackets[i].writePublicKey();
30805 pubSubkeyPacket = new PublicSubkeyPacket();
30806 pubSubkeyPacket.read(bytes);
30807 packetlist.push(pubSubkeyPacket);
30808 break;
30809 default:
30810 packetlist.push(keyPackets[i]);
30811 }
30812 }
30813 return new Key(packetlist);
30814 }
30815
30816 /**
30817 * Returns ASCII armored text of key
30818 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30819 * @returns {ReadableStream<String>} ASCII armor.
30820 */
30821 armor(config = defaultConfig) {
30822 const type = this.isPublic() ? enums.armor.publicKey : enums.armor.privateKey;
30823 return armor(type, this.toPacketlist().write(), undefined, undefined, undefined, config);
30824 }
30825
30826 /**
30827 * Returns last created key or key by given keyId that is available for signing and verification
30828 * @param {module:type/keyid~Keyid} keyId, optional
30829 * @param {Date} [date] - Use the given date for verification instead of the current time
30830 * @param {Object} userId, optional user ID
30831 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30832 * @returns {Key|SubKey|null} Key or null if no signing key has been found.
30833 * @async
30834 */
30835 async getSigningKey(keyId = null, date = new Date(), userId = {}, config = defaultConfig) {
30836 await this.verifyPrimaryKey(date, userId, config);
30837 const primaryKey = this.keyPacket;
30838 const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
30839 let exception;
30840 for (let i = 0; i < subKeys.length; i++) {
30841 if (!keyId || subKeys[i].getKeyId().equals(keyId)) {
30842 try {
30843 await subKeys[i].verify(primaryKey, date, config);
30844 const dataToVerify = { key: primaryKey, bind: subKeys[i].keyPacket };
30845 const bindingSignature = await getLatestValidSignature(subKeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
30846 if (
30847 bindingSignature &&
30848 bindingSignature.embeddedSignature &&
30849 isValidSigningKeyPacket(subKeys[i].keyPacket, bindingSignature) &&
30850 await getLatestValidSignature([bindingSignature.embeddedSignature], subKeys[i].keyPacket, enums.signature.keyBinding, dataToVerify, date, config)
30851 ) {
30852 return subKeys[i];
30853 }
30854 } catch (e) {
30855 exception = e;
30856 }
30857 }
30858 }
30859 const primaryUser = await this.getPrimaryUser(date, userId, config);
30860 if ((!keyId || primaryKey.getKeyId().equals(keyId)) &&
30861 isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification)) {
30862 return this;
30863 }
30864 throw util.wrapError('Could not find valid signing key packet in key ' + this.getKeyId().toHex(), exception);
30865 }
30866
30867 /**
30868 * Returns last created key or key by given keyId that is available for encryption or decryption
30869 * @param {module:type/keyid~Keyid} keyId, optional
30870 * @param {Date} date, optional
30871 * @param {String} userId, optional
30872 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30873 * @returns {Key|SubKey|null} Key or null if no encryption key has been found.
30874 * @async
30875 */
30876 async getEncryptionKey(keyId, date = new Date(), userId = {}, config = defaultConfig) {
30877 await this.verifyPrimaryKey(date, userId, config);
30878 const primaryKey = this.keyPacket;
30879 // V4: by convention subkeys are preferred for encryption service
30880 const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
30881 let exception;
30882 for (let i = 0; i < subKeys.length; i++) {
30883 if (!keyId || subKeys[i].getKeyId().equals(keyId)) {
30884 try {
30885 await subKeys[i].verify(primaryKey, date, config);
30886 const dataToVerify = { key: primaryKey, bind: subKeys[i].keyPacket };
30887 const bindingSignature = await getLatestValidSignature(subKeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
30888 if (bindingSignature && isValidEncryptionKeyPacket(subKeys[i].keyPacket, bindingSignature)) {
30889 return subKeys[i];
30890 }
30891 } catch (e) {
30892 exception = e;
30893 }
30894 }
30895 }
30896 // if no valid subkey for encryption, evaluate primary key
30897 const primaryUser = await this.getPrimaryUser(date, userId, config);
30898 if ((!keyId || primaryKey.getKeyId().equals(keyId)) &&
30899 isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) {
30900 return this;
30901 }
30902 throw util.wrapError('Could not find valid encryption key packet in key ' + this.getKeyId().toHex(), exception);
30903 }
30904
30905 /**
30906 * Returns all keys that are available for decryption, matching the keyId when given
30907 * This is useful to retrieve keys for session key decryption
30908 * @param {module:type/keyid~Keyid} keyId, optional
30909 * @param {Date} date, optional
30910 * @param {String} userId, optional
30911 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30912 * @returns {Array<Key|SubKey>} Array of decryption keys.
30913 * @async
30914 */
30915 async getDecryptionKeys(keyId, date = new Date(), userId = {}, config = defaultConfig) {
30916 const primaryKey = this.keyPacket;
30917 const keys = [];
30918 for (let i = 0; i < this.subKeys.length; i++) {
30919 if (!keyId || this.subKeys[i].getKeyId().equals(keyId, true)) {
30920 try {
30921 const dataToVerify = { key: primaryKey, bind: this.subKeys[i].keyPacket };
30922 const bindingSignature = await getLatestValidSignature(this.subKeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
30923 if (bindingSignature && isValidDecryptionKeyPacket(bindingSignature, config)) {
30924 keys.push(this.subKeys[i]);
30925 }
30926 } catch (e) {}
30927 }
30928 }
30929
30930 // evaluate primary key
30931 const primaryUser = await this.getPrimaryUser(date, userId, config);
30932 if ((!keyId || primaryKey.getKeyId().equals(keyId, true)) &&
30933 isValidDecryptionKeyPacket(primaryUser.selfCertification, config)) {
30934 keys.push(this);
30935 }
30936
30937 return keys;
30938 }
30939
30940 /**
30941 * Encrypts all secret key and subkey packets matching keyId
30942 * @param {String|Array<String>} passphrases - If multiple passphrases, then should be in same order as packets each should encrypt
30943 * @param {module:type/keyid~Keyid} keyId
30944 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30945 * @throws {Error} if encryption failed for any key or subkey
30946 * @async
30947 */
30948 async encrypt(passphrases, keyId = null, config = defaultConfig) {
30949 if (!this.isPrivate()) {
30950 throw new Error("Nothing to encrypt in a public key");
30951 }
30952
30953 const keys = this.getKeys(keyId);
30954 passphrases = util.isArray(passphrases) ? passphrases : new Array(keys.length).fill(passphrases);
30955 if (passphrases.length !== keys.length) {
30956 throw new Error("Invalid number of passphrases for key");
30957 }
30958
30959 await Promise.all(keys.map(async function(key, i) {
30960 const { keyPacket } = key;
30961 await keyPacket.encrypt(passphrases[i], config);
30962 keyPacket.clearPrivateParams();
30963 }));
30964 }
30965
30966 /**
30967 * Decrypts all secret key and subkey packets matching keyId
30968 * @param {String|Array<String>} passphrases
30969 * @param {module:type/keyid~Keyid} keyId
30970 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30971 * @throws {Error} if any matching key or subkey packets did not decrypt successfully
30972 * @async
30973 */
30974 async decrypt(passphrases, keyId = null, config = defaultConfig) {
30975 if (!this.isPrivate()) {
30976 throw new Error("Nothing to decrypt in a public key");
30977 }
30978 passphrases = util.isArray(passphrases) ? passphrases : [passphrases];
30979
30980 await Promise.all(this.getKeys(keyId).map(async function(key) {
30981 let decrypted = false;
30982 let error = null;
30983 await Promise.all(passphrases.map(async function(passphrase) {
30984 try {
30985 await key.keyPacket.decrypt(passphrase);
30986 // If we are decrypting a single key packet, we also validate it directly
30987 if (keyId) await key.keyPacket.validate();
30988 decrypted = true;
30989 } catch (e) {
30990 error = e;
30991 }
30992 }));
30993 if (!decrypted) {
30994 throw error;
30995 }
30996 }));
30997
30998 if (!keyId) {
30999 // The full key should be decrypted and we can validate it all
31000 await this.validate(config);
31001 }
31002 }
31003
31004 /**
31005 * Returns true if the primary key or any subkey is decrypted.
31006 * A dummy key is considered encrypted.
31007 */
31008 isDecrypted() {
31009 return this.getKeys().some(({ keyPacket }) => keyPacket.isDecrypted());
31010 }
31011
31012 /**
31013 * Check whether the private and public primary key parameters correspond
31014 * Together with verification of binding signatures, this guarantees key integrity
31015 * In case of gnu-dummy primary key, it is enough to validate any signing subkeys
31016 * otherwise all encryption subkeys are validated
31017 * If only gnu-dummy keys are found, we cannot properly validate so we throw an error
31018 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31019 * @throws {Error} if validation was not successful and the key cannot be trusted
31020 * @async
31021 */
31022 async validate(config = defaultConfig) {
31023 if (!this.isPrivate()) {
31024 throw new Error("Cannot validate a public key");
31025 }
31026
31027 let signingKeyPacket;
31028 if (!this.primaryKey.isDummy()) {
31029 signingKeyPacket = this.primaryKey;
31030 } else {
31031 /**
31032 * It is enough to validate any signing keys
31033 * since its binding signatures are also checked
31034 */
31035 const signingKey = await this.getSigningKey(null, null, undefined, config);
31036 // This could again be a dummy key
31037 if (signingKey && !signingKey.keyPacket.isDummy()) {
31038 signingKeyPacket = signingKey.keyPacket;
31039 }
31040 }
31041
31042 if (signingKeyPacket) {
31043 return signingKeyPacket.validate();
31044 } else {
31045 const keys = this.getKeys();
31046 const allDummies = keys.map(key => key.keyPacket.isDummy()).every(Boolean);
31047 if (allDummies) {
31048 throw new Error("Cannot validate an all-gnu-dummy key");
31049 }
31050
31051 return Promise.all(keys.map(async key => key.keyPacket.validate()));
31052 }
31053 }
31054
31055 /**
31056 * Clear private key parameters
31057 */
31058 clearPrivateParams() {
31059 if (!this.isPrivate()) {
31060 throw new Error("Can't clear private parameters of a public key");
31061 }
31062 this.getKeys().forEach(({ keyPacket }) => {
31063 if (keyPacket.isDecrypted()) {
31064 keyPacket.clearPrivateParams();
31065 }
31066 });
31067 }
31068
31069 /**
31070 * Checks if a signature on a key is revoked
31071 * @param {SignaturePacket} signature - The signature to verify
31072 * @param {PublicSubkeyPacket|
31073 * SecretSubkeyPacket|
31074 * PublicKeyPacket|
31075 * SecretKeyPacket} key, optional The key to verify the signature
31076 * @param {Date} date - Use the given date instead of the current time
31077 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31078 * @returns {Boolean} True if the certificate is revoked.
31079 * @async
31080 */
31081 async isRevoked(signature, key, date = new Date(), config = defaultConfig) {
31082 return isDataRevoked(
31083 this.keyPacket, enums.signature.keyRevocation, { key: this.keyPacket }, this.revocationSignatures, signature, key, date, config
31084 );
31085 }
31086
31087 /**
31088 * Verify primary key. Checks for revocation signatures, expiration time
31089 * and valid self signature. Throws if the primary key is invalid.
31090 * @param {Date} [date] - Use the given date for verification instead of the current time
31091 * @param {Object} [userId] - User ID
31092 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31093 * @throws {Error} If key verification failed
31094 * @async
31095 */
31096 async verifyPrimaryKey(date = new Date(), userId = {}, config = defaultConfig) {
31097 const primaryKey = this.keyPacket;
31098 // check for key revocation signatures
31099 if (await this.isRevoked(null, null, date, config)) {
31100 throw new Error('Primary key is revoked');
31101 }
31102 // check for valid, unrevoked, unexpired self signature
31103 const { selfCertification } = await this.getPrimaryUser(date, userId, config);
31104 // check for expiration time
31105 if (isDataExpired(primaryKey, selfCertification, date)) {
31106 throw new Error('Primary key is expired');
31107 }
31108 }
31109
31110 /**
31111 * Returns the latest date when the key can be used for encrypting, signing, or both, depending on the `capabilities` paramater.
31112 * When `capabilities` is null, defaults to returning the expiry date of the primary key.
31113 * Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid.
31114 * Returns Infinity if the key doesn't expire.
31115 * @param {encrypt|sign|encrypt_sign} capabilities, optional
31116 * @param {module:type/keyid~Keyid} keyId, optional
31117 * @param {Object} userId, optional user ID
31118 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31119 * @returns {Date | Infinity | null}
31120 * @async
31121 */
31122 async getExpirationTime(capabilities, keyId, userId, config = defaultConfig) {
31123 const primaryUser = await this.getPrimaryUser(null, userId, config);
31124 const selfCert = primaryUser.selfCertification;
31125 const keyExpiry = getExpirationTime(this.keyPacket, selfCert);
31126 const sigExpiry = selfCert.getExpirationTime();
31127 let expiry = keyExpiry < sigExpiry ? keyExpiry : sigExpiry;
31128 if (capabilities === 'encrypt' || capabilities === 'encrypt_sign') {
31129 const encryptKey =
31130 await this.getEncryptionKey(keyId, expiry, userId, config).catch(() => {}) ||
31131 await this.getEncryptionKey(keyId, null, userId, config).catch(() => {});
31132 if (!encryptKey) return null;
31133 const encryptExpiry = await encryptKey.getExpirationTime(this.keyPacket, undefined, config);
31134 if (encryptExpiry < expiry) expiry = encryptExpiry;
31135 }
31136 if (capabilities === 'sign' || capabilities === 'encrypt_sign') {
31137 const signKey =
31138 await this.getSigningKey(keyId, expiry, userId, config).catch(() => {}) ||
31139 await this.getSigningKey(keyId, null, userId, config).catch(() => {});
31140 if (!signKey) return null;
31141 const signExpiry = await signKey.getExpirationTime(this.keyPacket, undefined, config);
31142 if (signExpiry < expiry) expiry = signExpiry;
31143 }
31144 return expiry;
31145 }
31146
31147 /**
31148 * Returns primary user and most significant (latest valid) self signature
31149 * - if multiple primary users exist, returns the one with the latest self signature
31150 * - otherwise, returns the user with the latest self signature
31151 * @param {Date} [date] - Use the given date for verification instead of the current time
31152 * @param {Object} [userId] - User ID to get instead of the primary user, if it exists
31153 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31154 * @returns {Promise<{user: User,
31155 * selfCertification: SignaturePacket}>} The primary user and the self signature
31156 * @async
31157 */
31158 async getPrimaryUser(date = new Date(), userId = {}, config = defaultConfig) {
31159 const primaryKey = this.keyPacket;
31160 const users = [];
31161 let exception;
31162 for (let i = 0; i < this.users.length; i++) {
31163 try {
31164 const user = this.users[i];
31165 if (!user.userId) {
31166 continue;
31167 }
31168 if (
31169 (userId.name !== undefined && user.userId.name !== userId.name) ||
31170 (userId.email !== undefined && user.userId.email !== userId.email) ||
31171 (userId.comment !== undefined && user.userId.comment !== userId.comment)
31172 ) {
31173 throw new Error('Could not find user that matches that user ID');
31174 }
31175 const dataToVerify = { userId: user.userId, key: primaryKey };
31176 const selfCertification = await getLatestValidSignature(user.selfCertifications, primaryKey, enums.signature.certGeneric, dataToVerify, date, config);
31177 users.push({ index: i, user, selfCertification });
31178 } catch (e) {
31179 exception = e;
31180 }
31181 }
31182 if (!users.length) {
31183 throw exception || new Error('Could not find primary user');
31184 }
31185 await Promise.all(users.map(async function (a) {
31186 return a.user.revoked || a.user.isRevoked(primaryKey, a.selfCertification, null, date, config);
31187 }));
31188 // sort by primary user flag and signature creation time
31189 const primaryUser = users.sort(function(a, b) {
31190 const A = a.selfCertification;
31191 const B = b.selfCertification;
31192 return B.revoked - A.revoked || A.isPrimaryUserID - B.isPrimaryUserID || A.created - B.created;
31193 }).pop();
31194 const { user, selfCertification: cert } = primaryUser;
31195 if (cert.revoked || await user.isRevoked(primaryKey, cert, null, date, config)) {
31196 throw new Error('Primary user is revoked');
31197 }
31198 return primaryUser;
31199 }
31200
31201 /**
31202 * Update key with new components from specified key with same key ID:
31203 * users, subkeys, certificates are merged into the destination key,
31204 * duplicates and expired signatures are ignored.
31205 *
31206 * If the specified key is a private key and the destination key is public,
31207 * the destination key is transformed to a private key.
31208 * @param {Key} key - Source key to merge
31209 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31210 * @returns {undefined}
31211 * @async
31212 */
31213 async update(key, config = defaultConfig) {
31214 if (!this.hasSameFingerprintAs(key)) {
31215 throw new Error('Key update method: fingerprints of keys not equal');
31216 }
31217 if (this.isPublic() && key.isPrivate()) {
31218 // check for equal subkey packets
31219 const equal = (this.subKeys.length === key.subKeys.length) &&
31220 (this.subKeys.every(destSubKey => {
31221 return key.subKeys.some(srcSubKey => {
31222 return destSubKey.hasSameFingerprintAs(srcSubKey);
31223 });
31224 }));
31225 if (!equal) {
31226 throw new Error('Cannot update public key with private key if subkey mismatch');
31227 }
31228 this.keyPacket = key.keyPacket;
31229 }
31230 // revocation signatures
31231 await mergeSignatures(key, this, 'revocationSignatures', srcRevSig => {
31232 return isDataRevoked(this.keyPacket, enums.signature.keyRevocation, this, [srcRevSig], null, key.keyPacket, undefined, config);
31233 });
31234 // direct signatures
31235 await mergeSignatures(key, this, 'directSignatures');
31236 // TODO replace when Promise.some or Promise.any are implemented
31237 // users
31238 await Promise.all(key.users.map(async srcUser => {
31239 let found = false;
31240 await Promise.all(this.users.map(async dstUser => {
31241 if ((srcUser.userId && dstUser.userId &&
31242 (srcUser.userId.userid === dstUser.userId.userid)) ||
31243 (srcUser.userAttribute && (srcUser.userAttribute.equals(dstUser.userAttribute)))) {
31244 await dstUser.update(srcUser, this.keyPacket, config);
31245 found = true;
31246 }
31247 }));
31248 if (!found) {
31249 this.users.push(srcUser);
31250 }
31251 }));
31252 // TODO replace when Promise.some or Promise.any are implemented
31253 // subkeys
31254 await Promise.all(key.subKeys.map(async srcSubKey => {
31255 let found = false;
31256 await Promise.all(this.subKeys.map(async dstSubKey => {
31257 if (dstSubKey.hasSameFingerprintAs(srcSubKey)) {
31258 await dstSubKey.update(srcSubKey, this.keyPacket, config);
31259 found = true;
31260 }
31261 }));
31262 if (!found) {
31263 this.subKeys.push(srcSubKey);
31264 }
31265 }));
31266 }
31267
31268 /**
31269 * Revokes the key
31270 * @param {Object} reasonForRevocation - optional, object indicating the reason for revocation
31271 * @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
31272 * @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
31273 * @param {Date} date - optional, override the creationtime of the revocation signature
31274 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31275 * @returns {Key} New key with revocation signature.
31276 * @async
31277 */
31278 async revoke(
31279 {
31280 flag: reasonForRevocationFlag = enums.reasonForRevocation.noReason,
31281 string: reasonForRevocationString = ''
31282 } = {},
31283 date = new Date(),
31284 config = defaultConfig
31285 ) {
31286 if (this.isPublic()) {
31287 throw new Error('Need private key for revoking');
31288 }
31289 const dataToSign = { key: this.keyPacket };
31290 const key = await this.clone();
31291 key.revocationSignatures.push(await createSignaturePacket(dataToSign, null, this.keyPacket, {
31292 signatureType: enums.signature.keyRevocation,
31293 reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
31294 reasonForRevocationString
31295 }, date, undefined, undefined, undefined, config));
31296 return key;
31297 }
31298
31299 /**
31300 * Get revocation certificate from a revoked key.
31301 * (To get a revocation certificate for an unrevoked key, call revoke() first.)
31302 * @param {Date} date - Use the given date instead of the current time
31303 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31304 * @returns {String} Armored revocation certificate.
31305 * @async
31306 */
31307 async getRevocationCertificate(date = new Date(), config = defaultConfig) {
31308 const dataToVerify = { key: this.keyPacket };
31309 const revocationSignature = await getLatestValidSignature(this.revocationSignatures, this.keyPacket, enums.signature.keyRevocation, dataToVerify, date, config);
31310 const packetlist = new PacketList();
31311 packetlist.push(revocationSignature);
31312 return armor(enums.armor.publicKey, packetlist.write(), null, null, 'This is a revocation certificate');
31313 }
31314
31315 /**
31316 * Applies a revocation certificate to a key
31317 * This adds the first signature packet in the armored text to the key,
31318 * if it is a valid revocation signature.
31319 * @param {String} revocationCertificate - armored revocation certificate
31320 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31321 * @returns {Key} New revoked key.
31322 * @async
31323 */
31324 async applyRevocationCertificate(revocationCertificate, config = defaultConfig) {
31325 const input = await unarmor(revocationCertificate, config);
31326 const packetlist = new PacketList();
31327 await packetlist.read(input.data, { SignaturePacket }, undefined, config);
31328 const revocationSignature = packetlist.findPacket(enums.packet.signature);
31329 if (!revocationSignature || revocationSignature.signatureType !== enums.signature.keyRevocation) {
31330 throw new Error('Could not find revocation signature packet');
31331 }
31332 if (!revocationSignature.issuerKeyId.equals(this.getKeyId())) {
31333 throw new Error('Revocation signature does not match key');
31334 }
31335 if (revocationSignature.isExpired()) {
31336 throw new Error('Revocation signature is expired');
31337 }
31338 try {
31339 await revocationSignature.verify(this.keyPacket, enums.signature.keyRevocation, { key: this.keyPacket }, undefined, undefined, config);
31340 } catch (e) {
31341 throw util.wrapError('Could not verify revocation signature', e);
31342 }
31343 const key = await this.clone();
31344 key.revocationSignatures.push(revocationSignature);
31345 return key;
31346 }
31347
31348 /**
31349 * Signs primary user of key
31350 * @param {Array<Key>} privateKeys - decrypted private keys for signing
31351 * @param {Date} [date] - Use the given date for verification instead of the current time
31352 * @param {Object} [userId] - User ID to get instead of the primary user, if it exists
31353 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31354 * @returns {Key} New public key with new certificate signature.
31355 * @async
31356 */
31357 async signPrimaryUser(privateKeys, date, userId, config = defaultConfig) {
31358 const { index, user } = await this.getPrimaryUser(date, userId, config);
31359 const userSign = await user.sign(this.keyPacket, privateKeys, config);
31360 const key = await this.clone();
31361 key.users[index] = userSign;
31362 return key;
31363 }
31364
31365 /**
31366 * Signs all users of key
31367 * @param {Array<Key>} privateKeys - decrypted private keys for signing
31368 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31369 * @returns {Key} New public key with new certificate signature.
31370 * @async
31371 */
31372 async signAllUsers(privateKeys, config = defaultConfig) {
31373 const that = this;
31374 const key = await this.clone();
31375 key.users = await Promise.all(this.users.map(function(user) {
31376 return user.sign(that.keyPacket, privateKeys, config);
31377 }));
31378 return key;
31379 }
31380
31381 /**
31382 * Verifies primary user of key
31383 * - if no arguments are given, verifies the self certificates;
31384 * - otherwise, verifies all certificates signed with given keys.
31385 * @param {Array<Key>} keys - array of keys to verify certificate signatures
31386 * @param {Date} [date] - Use the given date for verification instead of the current time
31387 * @param {Object} [userId] - User ID to get instead of the primary user, if it exists
31388 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31389 * @returns {Promise<Array<{keyid: module:type/keyid~Keyid,
31390 * valid: Boolean}>>} List of signer's keyid and validity of signature
31391 * @async
31392 */
31393 async verifyPrimaryUser(keys, date, userId, config = defaultConfig) {
31394 const primaryKey = this.keyPacket;
31395 const { user } = await this.getPrimaryUser(date, userId, config);
31396 const results = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) :
31397 [{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
31398 return results;
31399 }
31400
31401 /**
31402 * Verifies all users of key
31403 * - if no arguments are given, verifies the self certificates;
31404 * - otherwise, verifies all certificates signed with given keys.
31405 * @param {Array<Key>} keys - array of keys to verify certificate signatures
31406 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31407 * @returns {Promise<Array<{userid: String,
31408 * keyid: module:type/keyid~Keyid,
31409 * valid: Boolean}>>} list of userid, signer's keyid and validity of signature
31410 * @async
31411 */
31412 async verifyAllUsers(keys, config = defaultConfig) {
31413 const results = [];
31414 const primaryKey = this.keyPacket;
31415 await Promise.all(this.users.map(async function(user) {
31416 const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) :
31417 [{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
31418 signatures.forEach(signature => {
31419 results.push({
31420 userid: user.userId.userid,
31421 keyid: signature.keyid,
31422 valid: signature.valid
31423 });
31424 });
31425 }));
31426 return results;
31427 }
31428
31429 /**
31430 * Generates a new OpenPGP subkey, and returns a clone of the Key object with the new subkey added.
31431 * Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the primary key. DSA primary keys default to RSA subkeys.
31432 * @param {ecc|rsa} options.type The subkey algorithm: ECC or RSA
31433 * @param {String} options.curve (optional) Elliptic curve for ECC keys
31434 * @param {Integer} options.rsaBits (optional) Number of bits for RSA subkeys
31435 * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires
31436 * @param {Date} options.date (optional) Override the creation date of the key and the key signatures
31437 * @param {Boolean} options.sign (optional) Indicates whether the subkey should sign rather than encrypt. Defaults to false
31438 * @param {Object} options.config (optional) custom configuration settings to overwrite those in [config]{@link module:config}
31439 * @returns {Key}
31440 * @async
31441 */
31442 async addSubkey(options = {}) {
31443 const config = { ...defaultConfig, ...options.config };
31444 if (!this.isPrivate()) {
31445 throw new Error("Cannot add a subkey to a public key");
31446 }
31447 if (options.passphrase) {
31448 throw new Error("Subkey could not be encrypted here, please encrypt whole key");
31449 }
31450 if (options.rsaBits < config.minRsaBits) {
31451 throw new Error(`rsaBits should be at least ${config.minRsaBits}, got: ${options.rsaBits}`);
31452 }
31453 const secretKeyPacket = this.primaryKey;
31454 if (secretKeyPacket.isDummy()) {
31455 throw new Error("Cannot add subkey to gnu-dummy primary key");
31456 }
31457 if (!secretKeyPacket.isDecrypted()) {
31458 throw new Error("Key is not decrypted");
31459 }
31460 const defaultOptions = secretKeyPacket.getAlgorithmInfo();
31461 defaultOptions.type = defaultOptions.curve ? 'ecc' : 'rsa'; // DSA keys default to RSA
31462 defaultOptions.rsaBits = defaultOptions.bits || 4096;
31463 defaultOptions.curve = defaultOptions.curve || 'curve25519';
31464 options = sanitizeKeyOptions(options, defaultOptions);
31465 const keyPacket = await generateSecretSubkey(options);
31466 const bindingSignature = await createBindingSignature(keyPacket, secretKeyPacket, options, config);
31467 const packetList = this.toPacketlist();
31468 packetList.push(keyPacket);
31469 packetList.push(bindingSignature);
31470 return new Key(packetList);
31471 }
31472}
31473
31474['getKeyId', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'hasSameFingerprintAs'].forEach(name => {
31475 Key.prototype[name] =
31476 SubKey.prototype[name];
31477});
31478
31479// OpenPGP.js - An OpenPGP implementation in javascript
31480
31481/**
31482 * Generates a new OpenPGP key. Supports RSA and ECC keys.
31483 * By default, primary and subkeys will be of same type.
31484 * @param {ecc|rsa} options.type The primary key algorithm type: ECC or RSA
31485 * @param {String} options.curve Elliptic curve for ECC keys
31486 * @param {Integer} options.rsaBits Number of bits for RSA keys
31487 * @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' }
31488 * @param {String} options.passphrase Passphrase used to encrypt the resulting private key
31489 * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires
31490 * @param {Date} options.date Creation date of the key and the key signatures
31491 * @param {Object} config - Full configuration
31492 * @param {Array<Object>} options.subkeys (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}]
31493 * sign parameter defaults to false, and indicates whether the subkey should sign rather than encrypt
31494 * @returns {Key}
31495 * @async
31496 * @static
31497 * @private
31498 */
31499async function generate$2(options, config) {
31500 options.sign = true; // primary key is always a signing key
31501 options = sanitizeKeyOptions(options);
31502 options.subkeys = options.subkeys.map((subkey, index) => sanitizeKeyOptions(options.subkeys[index], options));
31503 let promises = [generateSecretKey(options, config)];
31504 promises = promises.concat(options.subkeys.map(options => generateSecretSubkey(options, config)));
31505 return Promise.all(promises).then(packets => wrapKeyObject(packets[0], packets.slice(1), options, config));
31506}
31507
31508/**
31509 * Reformats and signs an OpenPGP key with a given User ID. Currently only supports RSA keys.
31510 * @param {Key} options.privateKey The private key to reformat
31511 * @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' }
31512 * @param {String} options.passphrase Passphrase used to encrypt the resulting private key
31513 * @param {Number} options.keyExpirationTime Number of seconds from the key creation time after which the key expires
31514 * @param {Date} options.date Override the creation date of the key and the key signatures
31515 * @param {Array<Object>} options.subkeys (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}]
31516 * @param {Object} config - Full configuration
31517 *
31518 * @returns {Key}
31519 * @async
31520 * @static
31521 * @private
31522 */
31523async function reformat(options, config) {
31524 options = sanitize(options);
31525
31526 if (options.privateKey.primaryKey.isDummy()) {
31527 throw new Error('Cannot reformat a gnu-dummy primary key');
31528 }
31529
31530 const isDecrypted = options.privateKey.getKeys().every(({ keyPacket }) => keyPacket.isDecrypted());
31531 if (!isDecrypted) {
31532 throw new Error('Key is not decrypted');
31533 }
31534
31535 const packetlist = options.privateKey.toPacketlist();
31536 let secretKeyPacket;
31537 const secretSubkeyPackets = [];
31538 for (let i = 0; i < packetlist.length; i++) {
31539 if (packetlist[i].tag === enums.packet.secretKey) {
31540 secretKeyPacket = packetlist[i];
31541 } else if (packetlist[i].tag === enums.packet.secretSubkey) {
31542 secretSubkeyPackets.push(packetlist[i]);
31543 }
31544 }
31545 if (!secretKeyPacket) {
31546 throw new Error('Key does not contain a secret key packet');
31547 }
31548
31549 if (!options.subkeys) {
31550 options.subkeys = await Promise.all(secretSubkeyPackets.map(async secretSubkeyPacket => ({
31551 sign: await options.privateKey.getSigningKey(secretSubkeyPacket.getKeyId(), null, undefined, config).catch(() => {}) &&
31552 !await options.privateKey.getEncryptionKey(secretSubkeyPacket.getKeyId(), null, undefined, config).catch(() => {})
31553 })));
31554 }
31555
31556 if (options.subkeys.length !== secretSubkeyPackets.length) {
31557 throw new Error('Number of subkey options does not match number of subkeys');
31558 }
31559
31560 options.subkeys = options.subkeys.map(function(subkey, index) { return sanitize(options.subkeys[index], options); });
31561
31562 return wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config);
31563
31564 function sanitize(options, subkeyDefaults = {}) {
31565 options.keyExpirationTime = options.keyExpirationTime || subkeyDefaults.keyExpirationTime;
31566 options.passphrase = util.isString(options.passphrase) ? options.passphrase : subkeyDefaults.passphrase;
31567 options.date = options.date || subkeyDefaults.date;
31568
31569 return options;
31570 }
31571}
31572
31573
31574async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config) {
31575 // set passphrase protection
31576 if (options.passphrase) {
31577 await secretKeyPacket.encrypt(options.passphrase, config);
31578 }
31579
31580 await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
31581 const subkeyPassphrase = options.subkeys[index].passphrase;
31582 if (subkeyPassphrase) {
31583 await secretSubkeyPacket.encrypt(subkeyPassphrase, config);
31584 }
31585 }));
31586
31587 const packetlist = new PacketList();
31588
31589 packetlist.push(secretKeyPacket);
31590
31591 await Promise.all(options.userIds.map(async function(userId, index) {
31592 function createdPreferredAlgos(algos, configAlgo) {
31593 if (configAlgo) { // Not `uncompressed` / `plaintext`
31594 const configIndex = algos.indexOf(configAlgo);
31595 if (configIndex >= 1) { // If it is included and not in first place,
31596 algos.splice(configIndex, 1); // remove it.
31597 }
31598 if (configIndex !== 0) { // If it was included and not in first place, or wasn't included,
31599 algos.unshift(configAlgo); // add it to the front.
31600 }
31601 }
31602 return algos;
31603 }
31604
31605 const userIdPacket = UserIDPacket.fromObject(userId);
31606 const dataToSign = {};
31607 dataToSign.userId = userIdPacket;
31608 dataToSign.key = secretKeyPacket;
31609 const signaturePacket = new SignaturePacket(options.date);
31610 signaturePacket.signatureType = enums.signature.certGeneric;
31611 signaturePacket.publicKeyAlgorithm = secretKeyPacket.algorithm;
31612 signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, secretKeyPacket, undefined, undefined, config);
31613 signaturePacket.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
31614 signaturePacket.preferredSymmetricAlgorithms = createdPreferredAlgos([
31615 // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support)
31616 enums.symmetric.aes256,
31617 enums.symmetric.aes128,
31618 enums.symmetric.aes192
31619 ], config.encryptionCipher);
31620 if (config.aeadProtect) {
31621 signaturePacket.preferredAeadAlgorithms = createdPreferredAlgos([
31622 enums.aead.eax,
31623 enums.aead.ocb
31624 ], config.aeadMode);
31625 }
31626 signaturePacket.preferredHashAlgorithms = createdPreferredAlgos([
31627 // prefer fast asm.js implementations (SHA-256)
31628 enums.hash.sha256,
31629 enums.hash.sha512
31630 ], config.preferHashAlgorithm);
31631 signaturePacket.preferredCompressionAlgorithms = createdPreferredAlgos([
31632 enums.compression.zlib,
31633 enums.compression.zip,
31634 enums.compression.uncompressed
31635 ], config.compression);
31636 if (index === 0) {
31637 signaturePacket.isPrimaryUserID = true;
31638 }
31639 // integrity protection always enabled
31640 signaturePacket.features = [0];
31641 signaturePacket.features[0] |= enums.features.modificationDetection;
31642 if (config.aeadProtect) {
31643 signaturePacket.features[0] |= enums.features.aead;
31644 }
31645 if (config.v5Keys) {
31646 signaturePacket.features[0] |= enums.features.v5Keys;
31647 }
31648 if (options.keyExpirationTime > 0) {
31649 signaturePacket.keyExpirationTime = options.keyExpirationTime;
31650 signaturePacket.keyNeverExpires = false;
31651 }
31652 await signaturePacket.sign(secretKeyPacket, dataToSign);
31653
31654 return { userIdPacket, signaturePacket };
31655 })).then(list => {
31656 list.forEach(({ userIdPacket, signaturePacket }) => {
31657 packetlist.push(userIdPacket);
31658 packetlist.push(signaturePacket);
31659 });
31660 });
31661
31662 await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
31663 const subkeyOptions = options.subkeys[index];
31664 const subkeySignaturePacket = await createBindingSignature(secretSubkeyPacket, secretKeyPacket, subkeyOptions, config);
31665 return { secretSubkeyPacket, subkeySignaturePacket };
31666 })).then(packets => {
31667 packets.forEach(({ secretSubkeyPacket, subkeySignaturePacket }) => {
31668 packetlist.push(secretSubkeyPacket);
31669 packetlist.push(subkeySignaturePacket);
31670 });
31671 });
31672
31673 // Add revocation signature packet for creating a revocation certificate.
31674 // This packet should be removed before returning the key.
31675 const dataToSign = { key: secretKeyPacket };
31676 packetlist.push(await createSignaturePacket(dataToSign, null, secretKeyPacket, {
31677 signatureType: enums.signature.keyRevocation,
31678 reasonForRevocationFlag: enums.reasonForRevocation.noReason,
31679 reasonForRevocationString: ''
31680 }, options.date, undefined, undefined, undefined, config));
31681
31682 // set passphrase protection
31683 if (options.passphrase) {
31684 secretKeyPacket.clearPrivateParams();
31685 }
31686
31687 await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
31688 const subkeyPassphrase = options.subkeys[index].passphrase;
31689 if (subkeyPassphrase) {
31690 secretSubkeyPacket.clearPrivateParams();
31691 }
31692 }));
31693
31694 return new Key(packetlist);
31695}
31696
31697/**
31698 * Reads an (optionally armored) OpenPGP key and returns a key object
31699 * @param {Object} options
31700 * @param {String | ReadableStream<String>} [options.armoredKey] - Armored key to be parsed
31701 * @param {Uint8Array | ReadableStream<Uint8Array>} [options.binaryKey] - Binary key to be parsed
31702 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
31703 * @returns {Key} Key object.
31704 * @async
31705 * @static
31706 */
31707async function readKey({ armoredKey, binaryKey, config }) {
31708 config = { ...defaultConfig, ...config };
31709 if (!armoredKey && !binaryKey) {
31710 throw new Error('readKey: must pass options object containing `armoredKey` or `binaryKey`');
31711 }
31712 let input;
31713 if (armoredKey) {
31714 const { type, data } = await unarmor(armoredKey, config);
31715 if (!(type === enums.armor.publicKey || type === enums.armor.privateKey)) {
31716 throw new Error('Armored text not of type key');
31717 }
31718 input = data;
31719 } else {
31720 input = binaryKey;
31721 }
31722 const packetlist = new PacketList();
31723 await packetlist.read(input, allowedKeyPackets, undefined, config);
31724 return new Key(packetlist);
31725}
31726
31727/**
31728 * Reads an (optionally armored) OpenPGP key block and returns a list of key objects
31729 * @param {Object} options
31730 * @param {String | ReadableStream<String>} [options.armoredKeys] - Armored keys to be parsed
31731 * @param {Uint8Array | ReadableStream<Uint8Array>} [options.binaryKeys] - Binary keys to be parsed
31732 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
31733 * @returns {Array<Key>} Key objects.
31734 * @async
31735 * @static
31736 */
31737async function readKeys({ armoredKeys, binaryKeys, config }) {
31738 config = { ...defaultConfig, ...config };
31739 let input = armoredKeys || binaryKeys;
31740 if (!input) {
31741 throw new Error('readKeys: must pass options object containing `armoredKeys` or `binaryKeys`');
31742 }
31743 if (armoredKeys) {
31744 const { type, data } = await unarmor(armoredKeys, config);
31745 if (type !== enums.armor.publicKey && type !== enums.armor.privateKey) {
31746 throw new Error('Armored text not of type key');
31747 }
31748 input = data;
31749 }
31750 const keys = [];
31751 const packetlist = new PacketList();
31752 await packetlist.read(input, allowedKeyPackets, undefined, config);
31753 const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey);
31754 if (keyIndex.length === 0) {
31755 throw new Error('No key packet found');
31756 }
31757 for (let i = 0; i < keyIndex.length; i++) {
31758 const oneKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
31759 const newKey = new Key(oneKeyList);
31760 keys.push(newKey);
31761 }
31762 return keys;
31763}
31764
31765// GPG4Browsers - An OpenPGP implementation in javascript
31766
31767
31768/**
31769 * Class that represents an OpenPGP message.
31770 * Can be an encrypted message, signed message, compressed message or literal message
31771 * See {@link https://tools.ietf.org/html/rfc4880#section-11.3}
31772 */
31773class Message {
31774 /**
31775 * @param {PacketList} packetlist - The packets that form this message
31776 */
31777 constructor(packetlist) {
31778 this.packets = packetlist || new PacketList();
31779 }
31780
31781 /**
31782 * Returns the key IDs of the keys to which the session key is encrypted
31783 * @returns {Array<module:type/keyid~Keyid>} Array of keyid objects.
31784 */
31785 getEncryptionKeyIds() {
31786 const keyIds = [];
31787 const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
31788 pkESKeyPacketlist.forEach(function(packet) {
31789 keyIds.push(packet.publicKeyId);
31790 });
31791 return keyIds;
31792 }
31793
31794 /**
31795 * Returns the key IDs of the keys that signed the message
31796 * @returns {Array<module:type/keyid~Keyid>} Array of keyid objects.
31797 */
31798 getSigningKeyIds() {
31799 const keyIds = [];
31800 const msg = this.unwrapCompressed();
31801 // search for one pass signatures
31802 const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature);
31803 onePassSigList.forEach(function(packet) {
31804 keyIds.push(packet.issuerKeyId);
31805 });
31806 // if nothing found look for signature packets
31807 if (!keyIds.length) {
31808 const signatureList = msg.packets.filterByTag(enums.packet.signature);
31809 signatureList.forEach(function(packet) {
31810 keyIds.push(packet.issuerKeyId);
31811 });
31812 }
31813 return keyIds;
31814 }
31815
31816 /**
31817 * Decrypt the message. Either a private key, a session key, or a password must be specified.
31818 * @param {Array<Key>} [privateKeys] - Private keys with decrypted secret data
31819 * @param {Array<String>} [passwords] - Passwords used to decrypt
31820 * @param {Array<Object>} [sessionKeys] - Session keys in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] }
31821 * @param {Boolean} [streaming] - Whether to process data as a stream
31822 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31823 * @returns {Message} New message with decrypted content.
31824 * @async
31825 */
31826 async decrypt(privateKeys, passwords, sessionKeys, streaming, config = defaultConfig) {
31827 const keyObjs = sessionKeys || await this.decryptSessionKeys(privateKeys, passwords, config);
31828
31829 const symEncryptedPacketlist = this.packets.filterByTag(
31830 enums.packet.symmetricallyEncryptedData,
31831 enums.packet.symEncryptedIntegrityProtectedData,
31832 enums.packet.AEADEncryptedData
31833 );
31834
31835 if (symEncryptedPacketlist.length === 0) {
31836 return this;
31837 }
31838
31839 const symEncryptedPacket = symEncryptedPacketlist[0];
31840 let exception = null;
31841 const decryptedPromise = Promise.all(keyObjs.map(async keyObj => {
31842 if (!keyObj || !util.isUint8Array(keyObj.data) || !util.isString(keyObj.algorithm)) {
31843 throw new Error('Invalid session key for decryption.');
31844 }
31845
31846 try {
31847 await symEncryptedPacket.decrypt(keyObj.algorithm, keyObj.data, streaming, config);
31848 } catch (e) {
31849 util.printDebugError(e);
31850 exception = e;
31851 }
31852 }));
31853 // We don't await stream.cancel here because it only returns when the other copy is canceled too.
31854 stream.cancel(symEncryptedPacket.encrypted); // Don't keep copy of encrypted data in memory.
31855 symEncryptedPacket.encrypted = null;
31856 await decryptedPromise;
31857
31858 if (!symEncryptedPacket.packets || !symEncryptedPacket.packets.length) {
31859 throw exception || new Error('Decryption failed.');
31860 }
31861
31862 const resultMsg = new Message(symEncryptedPacket.packets);
31863 symEncryptedPacket.packets = new PacketList(); // remove packets after decryption
31864
31865 return resultMsg;
31866 }
31867
31868 /**
31869 * Decrypt encrypted session keys either with private keys or passwords.
31870 * @param {Array<Key>} [privateKeys] - Private keys with decrypted secret data
31871 * @param {Array<String>} [passwords] - Passwords used to decrypt
31872 * @param {Object} [config] - Full configuration, defaults to openpgp.config
31873 * @returns {Promise<Array<{ data: Uint8Array,
31874 algorithm: String }>>} array of object with potential sessionKey, algorithm pairs
31875 * @async
31876 */
31877 async decryptSessionKeys(privateKeys, passwords, config = defaultConfig) {
31878 let keyPackets = [];
31879
31880 let exception;
31881 if (passwords) {
31882 const symESKeyPacketlist = this.packets.filterByTag(enums.packet.symEncryptedSessionKey);
31883 if (!symESKeyPacketlist) {
31884 throw new Error('No symmetrically encrypted session key packet found.');
31885 }
31886 await Promise.all(passwords.map(async function(password, i) {
31887 let packets;
31888 if (i) {
31889 packets = new PacketList();
31890 await packets.read(symESKeyPacketlist.write(), { SymEncryptedSessionKeyPacket });
31891 } else {
31892 packets = symESKeyPacketlist;
31893 }
31894 await Promise.all(packets.map(async function(keyPacket) {
31895 try {
31896 await keyPacket.decrypt(password);
31897 keyPackets.push(keyPacket);
31898 } catch (err) {
31899 util.printDebugError(err);
31900 }
31901 }));
31902 }));
31903 } else if (privateKeys) {
31904 const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
31905 if (!pkESKeyPacketlist) {
31906 throw new Error('No public key encrypted session key packet found.');
31907 }
31908 await Promise.all(pkESKeyPacketlist.map(async function(keyPacket) {
31909 await Promise.all(privateKeys.map(async function(privateKey) {
31910 let algos = [
31911 enums.symmetric.aes256, // Old OpenPGP.js default fallback
31912 enums.symmetric.aes128, // RFC4880bis fallback
31913 enums.symmetric.tripledes, // RFC4880 fallback
31914 enums.symmetric.cast5 // Golang OpenPGP fallback
31915 ];
31916 try {
31917 const primaryUser = await privateKey.getPrimaryUser(undefined, undefined, config); // TODO: Pass userId from somewhere.
31918 if (primaryUser.selfCertification.preferredSymmetricAlgorithms) {
31919 algos = algos.concat(primaryUser.selfCertification.preferredSymmetricAlgorithms);
31920 }
31921 } catch (e) {}
31922
31923 // do not check key expiration to allow decryption of old messages
31924 const privateKeyPackets = (await privateKey.getDecryptionKeys(keyPacket.publicKeyId, null, undefined, config)).map(key => key.keyPacket);
31925 await Promise.all(privateKeyPackets.map(async function(privateKeyPacket) {
31926 if (!privateKeyPacket || privateKeyPacket.isDummy()) {
31927 return;
31928 }
31929 if (!privateKeyPacket.isDecrypted()) {
31930 throw new Error('Private key is not decrypted.');
31931 }
31932 try {
31933 await keyPacket.decrypt(privateKeyPacket);
31934 if (!algos.includes(enums.write(enums.symmetric, keyPacket.sessionKeyAlgorithm))) {
31935 throw new Error('A non-preferred symmetric algorithm was used.');
31936 }
31937 keyPackets.push(keyPacket);
31938 } catch (err) {
31939 util.printDebugError(err);
31940 exception = err;
31941 }
31942 }));
31943 }));
31944 stream.cancel(keyPacket.encrypted); // Don't keep copy of encrypted data in memory.
31945 keyPacket.encrypted = null;
31946 }));
31947 } else {
31948 throw new Error('No key or password specified.');
31949 }
31950
31951 if (keyPackets.length) {
31952 // Return only unique session keys
31953 if (keyPackets.length > 1) {
31954 const seen = {};
31955 keyPackets = keyPackets.filter(function(item) {
31956 const k = item.sessionKeyAlgorithm + util.uint8ArrayToStr(item.sessionKey);
31957 if (seen.hasOwnProperty(k)) {
31958 return false;
31959 }
31960 seen[k] = true;
31961 return true;
31962 });
31963 }
31964
31965 return keyPackets.map(packet => ({ data: packet.sessionKey, algorithm: packet.sessionKeyAlgorithm }));
31966 }
31967 throw exception || new Error('Session key decryption failed.');
31968 }
31969
31970 /**
31971 * Get literal data that is the body of the message
31972 * @returns {(Uint8Array|null)} Literal body of the message as Uint8Array.
31973 */
31974 getLiteralData() {
31975 const msg = this.unwrapCompressed();
31976 const literal = msg.packets.findPacket(enums.packet.literalData);
31977 return (literal && literal.getBytes()) || null;
31978 }
31979
31980 /**
31981 * Get filename from literal data packet
31982 * @returns {(String|null)} Filename of literal data packet as string.
31983 */
31984 getFilename() {
31985 const msg = this.unwrapCompressed();
31986 const literal = msg.packets.findPacket(enums.packet.literalData);
31987 return (literal && literal.getFilename()) || null;
31988 }
31989
31990 /**
31991 * Get literal data as text
31992 * @returns {(String|null)} Literal body of the message interpreted as text.
31993 */
31994 getText() {
31995 const msg = this.unwrapCompressed();
31996 const literal = msg.packets.findPacket(enums.packet.literalData);
31997 if (literal) {
31998 return literal.getText();
31999 }
32000 return null;
32001 }
32002
32003 /**
32004 * Generate a new session key object, taking the algorithm preferences of the passed public keys into account, if any.
32005 * @param {Array<Key>} [keys] - Public key(s) to select algorithm preferences for
32006 * @param {Date} [date] - Date to select algorithm preferences at
32007 * @param {Array<Object>} [userIds] - User IDs to select algorithm preferences for
32008 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32009 * @returns {{ data: Uint8Array, algorithm: String }} Object with session key data and algorithm.
32010 * @async
32011 */
32012 static async generateSessionKey(keys = [], date = new Date(), userIds = [], config = defaultConfig) {
32013 const algorithm = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', keys, date, userIds, config));
32014 const aeadAlgorithm = config.aeadProtect && await isAeadSupported(keys, date, userIds, config) ?
32015 enums.read(enums.aead, await getPreferredAlgo('aead', keys, date, userIds, config)) :
32016 undefined;
32017 const sessionKeyData = await mod.generateSessionKey(algorithm);
32018 return { data: sessionKeyData, algorithm, aeadAlgorithm };
32019 }
32020
32021 /**
32022 * Encrypt the message either with public keys, passwords, or both at once.
32023 * @param {Array<Key>} [keys] - Public key(s) for message encryption
32024 * @param {Array<String>} [passwords] - Password(s) for message encryption
32025 * @param {Object} [sessionKey] - Session key in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] }
32026 * @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
32027 * @param {Array<module:type/keyid~Keyid>} [encryptionKeyIds] - Array of key IDs to use for encryption. Each encryptionKeyIds[i] corresponds to publicKeys[i]
32028 * @param {Date} [date] - Override the creation date of the literal package
32029 * @param {Array<Object>} [userIds] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
32030 * @param {Boolean} [streaming] - Whether to process data as a stream
32031 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32032 * @returns {Message} New message with encrypted content.
32033 * @async
32034 */
32035 async encrypt(keys, passwords, sessionKey, wildcard = false, encryptionKeyIds = [], date = new Date(), userIds = [], streaming, config = defaultConfig) {
32036 if (sessionKey) {
32037 if (!util.isUint8Array(sessionKey.data) || !util.isString(sessionKey.algorithm)) {
32038 throw new Error('Invalid session key for encryption.');
32039 }
32040 } else if (keys && keys.length) {
32041 sessionKey = await Message.generateSessionKey(keys, date, userIds, config);
32042 } else if (passwords && passwords.length) {
32043 sessionKey = await Message.generateSessionKey(undefined, undefined, undefined, config);
32044 } else {
32045 throw new Error('No keys, passwords, or session key provided.');
32046 }
32047
32048 const { data: sessionKeyData, algorithm, aeadAlgorithm } = sessionKey;
32049
32050 const msg = await Message.encryptSessionKey(sessionKeyData, algorithm, aeadAlgorithm, keys, passwords, wildcard, encryptionKeyIds, date, userIds, config);
32051
32052 let symEncryptedPacket;
32053 if (aeadAlgorithm) {
32054 symEncryptedPacket = new AEADEncryptedDataPacket();
32055 symEncryptedPacket.aeadAlgorithm = aeadAlgorithm;
32056 } else {
32057 symEncryptedPacket = new SymEncryptedIntegrityProtectedDataPacket();
32058 }
32059 symEncryptedPacket.packets = this.packets;
32060
32061 await symEncryptedPacket.encrypt(algorithm, sessionKeyData, streaming, config);
32062
32063 msg.packets.push(symEncryptedPacket);
32064 symEncryptedPacket.packets = new PacketList(); // remove packets after encryption
32065 return msg;
32066 }
32067
32068 /**
32069 * Encrypt a session key either with public keys, passwords, or both at once.
32070 * @param {Uint8Array} sessionKey - session key for encryption
32071 * @param {String} algorithm - session key algorithm
32072 * @param {String} [aeadAlgorithm] - Aead algorithm, e.g. 'eax' or 'ocb'
32073 * @param {Array<Key>} [publicKeys] - Public key(s) for message encryption
32074 * @param {Array<String>} [passwords] - For message encryption
32075 * @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
32076 * @param {Array<module:type/keyid~Keyid>} [encryptionKeyIds] - Array of key IDs to use for encryption. Each encryptionKeyIds[i] corresponds to publicKeys[i]
32077 * @param {Date} [date] - Override the date
32078 * @param {Array} [userIds] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
32079 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32080 * @returns {Message} New message with encrypted content.
32081 * @async
32082 */
32083 static async encryptSessionKey(sessionKey, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard = false, encryptionKeyIds = [], date = new Date(), userIds = [], config = defaultConfig) {
32084 const packetlist = new PacketList();
32085
32086 if (publicKeys) {
32087 const results = await Promise.all(publicKeys.map(async function(publicKey, i) {
32088 const encryptionKey = await publicKey.getEncryptionKey(encryptionKeyIds[i], date, userIds, config);
32089 const pkESKeyPacket = new PublicKeyEncryptedSessionKeyPacket();
32090 pkESKeyPacket.publicKeyId = wildcard ? Keyid.wildcard() : encryptionKey.getKeyId();
32091 pkESKeyPacket.publicKeyAlgorithm = encryptionKey.keyPacket.algorithm;
32092 pkESKeyPacket.sessionKey = sessionKey;
32093 pkESKeyPacket.sessionKeyAlgorithm = algorithm;
32094 await pkESKeyPacket.encrypt(encryptionKey.keyPacket);
32095 delete pkESKeyPacket.sessionKey; // delete plaintext session key after encryption
32096 return pkESKeyPacket;
32097 }));
32098 packetlist.concat(results);
32099 }
32100 if (passwords) {
32101 const testDecrypt = async function(keyPacket, password) {
32102 try {
32103 await keyPacket.decrypt(password);
32104 return 1;
32105 } catch (e) {
32106 return 0;
32107 }
32108 };
32109
32110 const sum = (accumulator, currentValue) => accumulator + currentValue;
32111
32112 const encryptPassword = async function(sessionKey, algorithm, aeadAlgorithm, password) {
32113 const symEncryptedSessionKeyPacket = new SymEncryptedSessionKeyPacket(config);
32114 symEncryptedSessionKeyPacket.sessionKey = sessionKey;
32115 symEncryptedSessionKeyPacket.sessionKeyAlgorithm = algorithm;
32116 if (aeadAlgorithm) {
32117 symEncryptedSessionKeyPacket.aeadAlgorithm = aeadAlgorithm;
32118 }
32119 await symEncryptedSessionKeyPacket.encrypt(password, config);
32120
32121 if (config.passwordCollisionCheck) {
32122 const results = await Promise.all(passwords.map(pwd => testDecrypt(symEncryptedSessionKeyPacket, pwd)));
32123 if (results.reduce(sum) !== 1) {
32124 return encryptPassword(sessionKey, algorithm, password);
32125 }
32126 }
32127
32128 delete symEncryptedSessionKeyPacket.sessionKey; // delete plaintext session key after encryption
32129 return symEncryptedSessionKeyPacket;
32130 };
32131
32132 const results = await Promise.all(passwords.map(pwd => encryptPassword(sessionKey, algorithm, aeadAlgorithm, pwd)));
32133 packetlist.concat(results);
32134 }
32135
32136 return new Message(packetlist);
32137 }
32138
32139 /**
32140 * Sign the message (the literal data packet of the message)
32141 * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
32142 * @param {Signature} [signature] - Any existing detached signature to add to the message
32143 * @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i]
32144 * @param {Date} [date] - Override the creation time of the signature
32145 * @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
32146 * @param {Boolean} [streaming] - Whether to process data as a stream
32147 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32148 * @returns {Message} New message with signed content.
32149 * @async
32150 */
32151 async sign(privateKeys = [], signature = null, signingKeyIds = [], date = new Date(), userIds = [], streaming = false, config = defaultConfig) {
32152 const packetlist = new PacketList();
32153
32154 const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
32155 if (!literalDataPacket) {
32156 throw new Error('No literal data packet to sign.');
32157 }
32158
32159 let i;
32160 let existingSigPacketlist;
32161 // If data packet was created from Uint8Array, use binary, otherwise use text
32162 const signatureType = literalDataPacket.text === null ?
32163 enums.signature.binary : enums.signature.text;
32164
32165 if (signature) {
32166 existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
32167 for (i = existingSigPacketlist.length - 1; i >= 0; i--) {
32168 const signaturePacket = existingSigPacketlist[i];
32169 const onePassSig = new OnePassSignaturePacket();
32170 onePassSig.signatureType = signaturePacket.signatureType;
32171 onePassSig.hashAlgorithm = signaturePacket.hashAlgorithm;
32172 onePassSig.publicKeyAlgorithm = signaturePacket.publicKeyAlgorithm;
32173 onePassSig.issuerKeyId = signaturePacket.issuerKeyId;
32174 if (!privateKeys.length && i === 0) {
32175 onePassSig.flags = 1;
32176 }
32177 packetlist.push(onePassSig);
32178 }
32179 }
32180
32181 await Promise.all(Array.from(privateKeys).reverse().map(async function (privateKey, i) {
32182 if (privateKey.isPublic()) {
32183 throw new Error('Need private key for signing');
32184 }
32185 const signingKeyId = signingKeyIds[privateKeys.length - 1 - i];
32186 const signingKey = await privateKey.getSigningKey(signingKeyId, date, userIds, config);
32187 const onePassSig = new OnePassSignaturePacket();
32188 onePassSig.signatureType = signatureType;
32189 onePassSig.hashAlgorithm = await getPreferredHashAlgo$1(privateKey, signingKey.keyPacket, date, userIds, config);
32190 onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm;
32191 onePassSig.issuerKeyId = signingKey.getKeyId();
32192 if (i === privateKeys.length - 1) {
32193 onePassSig.flags = 1;
32194 }
32195 return onePassSig;
32196 })).then(onePassSignatureList => {
32197 onePassSignatureList.forEach(onePassSig => packetlist.push(onePassSig));
32198 });
32199
32200 packetlist.push(literalDataPacket);
32201 packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIds, false, streaming, config));
32202
32203 return new Message(packetlist);
32204 }
32205
32206 /**
32207 * Compresses the message (the literal and -if signed- signature data packets of the message)
32208 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32209 * @returns {Message} New message with compressed content.
32210 */
32211 compress(config = defaultConfig) {
32212 if (config.compression === enums.compression.uncompressed) {
32213 return this;
32214 }
32215
32216 const compressed = new CompressedDataPacket(config);
32217 compressed.packets = this.packets;
32218
32219 const packetList = new PacketList();
32220 packetList.push(compressed);
32221
32222 return new Message(packetList);
32223 }
32224
32225 /**
32226 * Create a detached signature for the message (the literal data packet of the message)
32227 * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
32228 * @param {Signature} [signature] - Any existing detached signature
32229 * @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i]
32230 * @param {Date} [date] - Override the creation time of the signature
32231 * @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
32232 * @param {Boolean} [streaming] - Whether to process data as a stream
32233 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32234 * @returns {Signature} New detached signature of message content.
32235 * @async
32236 */
32237 async signDetached(privateKeys = [], signature = null, signingKeyIds = [], date = new Date(), userIds = [], streaming = false, config = defaultConfig) {
32238 const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
32239 if (!literalDataPacket) {
32240 throw new Error('No literal data packet to sign.');
32241 }
32242 return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIds, true, streaming, config));
32243 }
32244
32245 /**
32246 * Verify message signatures
32247 * @param {Array<Key>} keys - Array of keys to verify signatures
32248 * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
32249 * @param {Boolean} [streaming] - Whether to process data as a stream
32250 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32251 * @returns {Array<({keyid: module:type/keyid~Keyid, valid: Boolean})>} List of signer's keyid and validity of signature.
32252 * @async
32253 */
32254 async verify(keys, date = new Date(), streaming, config = defaultConfig) {
32255 const msg = this.unwrapCompressed();
32256 const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
32257 if (literalDataList.length !== 1) {
32258 throw new Error('Can only verify message with one literal data packet.');
32259 }
32260 if (!streaming) {
32261 msg.packets.concat(await stream.readToEnd(msg.packets.stream, _ => _));
32262 }
32263 const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature).reverse();
32264 const signatureList = msg.packets.filterByTag(enums.packet.signature);
32265 if (streaming && onePassSigList.length && !signatureList.length && msg.packets.stream) {
32266 await Promise.all(onePassSigList.map(async onePassSig => {
32267 onePassSig.correspondingSig = new Promise((resolve, reject) => {
32268 onePassSig.correspondingSigResolve = resolve;
32269 onePassSig.correspondingSigReject = reject;
32270 });
32271 onePassSig.signatureData = stream.fromAsync(async () => (await onePassSig.correspondingSig).signatureData);
32272 onePassSig.hashed = stream.readToEnd(await onePassSig.hash(onePassSig.signatureType, literalDataList[0], undefined, false, streaming));
32273 onePassSig.hashed.catch(() => {});
32274 }));
32275 msg.packets.stream = stream.transformPair(msg.packets.stream, async (readable, writable) => {
32276 const reader = stream.getReader(readable);
32277 const writer = stream.getWriter(writable);
32278 try {
32279 for (let i = 0; i < onePassSigList.length; i++) {
32280 const { value: signature } = await reader.read();
32281 onePassSigList[i].correspondingSigResolve(signature);
32282 }
32283 await reader.readToEnd();
32284 await writer.ready;
32285 await writer.close();
32286 } catch (e) {
32287 onePassSigList.forEach(onePassSig => {
32288 onePassSig.correspondingSigReject(e);
32289 });
32290 await writer.abort(e);
32291 }
32292 });
32293 return createVerificationObjects(onePassSigList, literalDataList, keys, date, false, streaming, config);
32294 }
32295 return createVerificationObjects(signatureList, literalDataList, keys, date, false, streaming, config);
32296 }
32297
32298 /**
32299 * Verify detached message signature
32300 * @param {Array<Key>} keys - Array of keys to verify signatures
32301 * @param {Signature} signature
32302 * @param {Date} date - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
32303 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32304 * @returns {Array<({keyid: module:type/keyid~Keyid, valid: Boolean})>} List of signer's keyid and validity of signature.
32305 * @async
32306 */
32307 verifyDetached(signature, keys, date = new Date(), streaming, config = defaultConfig) {
32308 const msg = this.unwrapCompressed();
32309 const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
32310 if (literalDataList.length !== 1) {
32311 throw new Error('Can only verify message with one literal data packet.');
32312 }
32313 const signatureList = signature.packets;
32314 return createVerificationObjects(signatureList, literalDataList, keys, date, true, undefined, config);
32315 }
32316
32317 /**
32318 * Unwrap compressed message
32319 * @returns {Message} Message Content of compressed message.
32320 */
32321 unwrapCompressed() {
32322 const compressed = this.packets.filterByTag(enums.packet.compressedData);
32323 if (compressed.length) {
32324 return new Message(compressed[0].packets);
32325 }
32326 return this;
32327 }
32328
32329 /**
32330 * Append signature to unencrypted message object
32331 * @param {String|Uint8Array} detachedSignature - The detached ASCII-armored or Uint8Array PGP signature
32332 */
32333 async appendSignature(detachedSignature) {
32334 await this.packets.read(util.isUint8Array(detachedSignature) ? detachedSignature : (await unarmor(detachedSignature)).data, { SignaturePacket });
32335 }
32336
32337 /**
32338 * Returns binary encoded message
32339 * @returns {ReadableStream<Uint8Array>} Binary message.
32340 */
32341 write() {
32342 return this.packets.write();
32343 }
32344
32345 /**
32346 * Returns ASCII armored text of message
32347 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32348 * @returns {ReadableStream<String>} ASCII armor.
32349 */
32350 armor(config = defaultConfig) {
32351 return armor(enums.armor.message, this.write(), null, null, null, config);
32352 }
32353
32354 /**
32355 * Creates new message object from text.
32356 * @param {String | ReadableStream<String>} text - The message contents
32357 * @param {String} [filename=""] - Name of the file (if any)
32358 * @param {Date} [date=current date] - Date of the message, or modification date of the file
32359 * @param {'utf8'|'binary'|'text'|'mime'} [type='utf8'] - Data packet type
32360 * @returns {Message} New message object.
32361 * @static
32362 */
32363 static fromText(text, filename, date = new Date(), type = 'utf8') {
32364 const streamType = util.isStream(text);
32365 if (streamType === 'node') {
32366 text = stream.nodeToWeb(text);
32367 }
32368 const literalDataPacket = new LiteralDataPacket(date);
32369 // text will be converted to UTF8
32370 literalDataPacket.setText(text, type);
32371 if (filename !== undefined) {
32372 literalDataPacket.setFilename(filename);
32373 }
32374 const literalDataPacketlist = new PacketList();
32375 literalDataPacketlist.push(literalDataPacket);
32376 const message = new Message(literalDataPacketlist);
32377 message.fromStream = streamType;
32378 return message;
32379 }
32380
32381 /**
32382 * Creates new message object from binary data.
32383 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - The message contents
32384 * @param {String} [filename=""] - Name of the file (if any)
32385 * @param {Date} [date=current date] - Date of the message, or modification date of the file
32386 * @param {'utf8'|'binary'|'text'|'mime'} [type='binary'] - Data packet type
32387 * @returns {Message} New message object.
32388 * @static
32389 */
32390 static fromBinary(bytes, filename, date = new Date(), type = 'binary') {
32391 const streamType = util.isStream(bytes);
32392 if (!util.isUint8Array(bytes) && !streamType) {
32393 throw new Error('Data must be in the form of a Uint8Array or Stream');
32394 }
32395 if (streamType === 'node') {
32396 bytes = stream.nodeToWeb(bytes);
32397 }
32398
32399 const literalDataPacket = new LiteralDataPacket(date);
32400 literalDataPacket.setBytes(bytes, type);
32401 if (filename !== undefined) {
32402 literalDataPacket.setFilename(filename);
32403 }
32404 const literalDataPacketlist = new PacketList();
32405 literalDataPacketlist.push(literalDataPacket);
32406 const message = new Message(literalDataPacketlist);
32407 message.fromStream = streamType;
32408 return message;
32409 }
32410}
32411
32412/**
32413 * Create signature packets for the message
32414 * @param {LiteralDataPacket} literalDataPacket - the literal data packet to sign
32415 * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
32416 * @param {Signature} [signature] - Any existing detached signature to append
32417 * @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i]
32418 * @param {Date} [date] - Override the creationtime of the signature
32419 * @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
32420 * @param {Boolean} [detached] - Whether to create detached signature packets
32421 * @param {Boolean} [streaming] - Whether to process data as a stream
32422 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32423 * @returns {PacketList} List of signature packets.
32424 * @async
32425 * @private
32426 */
32427async function createSignaturePackets(literalDataPacket, privateKeys, signature = null, signingKeyIds = [], date = new Date(), userIds = [], detached = false, streaming = false, config = defaultConfig) {
32428 const packetlist = new PacketList();
32429
32430 // If data packet was created from Uint8Array, use binary, otherwise use text
32431 const signatureType = literalDataPacket.text === null ?
32432 enums.signature.binary : enums.signature.text;
32433
32434 await Promise.all(privateKeys.map(async (privateKey, i) => {
32435 const userId = userIds[i];
32436 if (privateKey.isPublic()) {
32437 throw new Error('Need private key for signing');
32438 }
32439 const signingKey = await privateKey.getSigningKey(signingKeyIds[i], date, userId, config);
32440 return createSignaturePacket(literalDataPacket, privateKey, signingKey.keyPacket, { signatureType }, date, userId, detached, streaming, config);
32441 })).then(signatureList => {
32442 signatureList.forEach(signaturePacket => packetlist.push(signaturePacket));
32443 });
32444
32445 if (signature) {
32446 const existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
32447 packetlist.concat(existingSigPacketlist);
32448 }
32449 return packetlist;
32450}
32451
32452/**
32453 * Create object containing signer's keyid and validity of signature
32454 * @param {SignaturePacket} signature - Signature packets
32455 * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
32456 * @param {Array<Key>} keys - Array of keys to verify signatures
32457 * @param {Date} date - Verify the signature against the given date,
32458 * i.e. check signature creation time < date < expiration time
32459 * @param {Boolean} [detached] - Whether to verify detached signature packets
32460 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32461 * @returns {Promise<Array<{keyid: module:type/keyid~Keyid,
32462 * valid: Boolean|null}>>} list of signer's keyid and validity of signature
32463 * @async
32464 * @private
32465 */
32466async function createVerificationObject(signature, literalDataList, keys, date = new Date(), detached = false, streaming = false, config = defaultConfig) {
32467 let primaryKey = null;
32468 let signingKey = null;
32469 await Promise.all(keys.map(async function(key) {
32470 // Look for the unique key that matches issuerKeyId of signature
32471 try {
32472 signingKey = await key.getSigningKey(signature.issuerKeyId, null, undefined, config);
32473 primaryKey = key;
32474 } catch (e) {}
32475 }));
32476
32477 const signaturePacket = signature.correspondingSig || signature;
32478 const verifiedSig = {
32479 keyid: signature.issuerKeyId,
32480 verified: (async () => {
32481 if (!signingKey) {
32482 return null;
32483 }
32484 await signature.verify(signingKey.keyPacket, signature.signatureType, literalDataList[0], detached, streaming, config);
32485 const sig = await signaturePacket;
32486 if (sig.isExpired(date) || !(
32487 sig.created >= signingKey.getCreationTime() &&
32488 sig.created < await (signingKey === primaryKey ?
32489 signingKey.getExpirationTime(undefined, undefined, undefined, config) :
32490 signingKey.getExpirationTime(primaryKey, date, undefined, config)
32491 )
32492 )) {
32493 throw new Error('Signature is expired');
32494 }
32495 return true;
32496 })(),
32497 signature: (async () => {
32498 const sig = await signaturePacket;
32499 const packetlist = new PacketList();
32500 packetlist.push(sig);
32501 return new Signature(packetlist);
32502 })()
32503 };
32504
32505 // Mark potential promise rejections as "handled". This is needed because in
32506 // some cases, we reject them before the user has a reasonable chance to
32507 // handle them (e.g. `await readToEnd(result.data); await result.verified` and
32508 // the data stream errors).
32509 verifiedSig.signature.catch(() => {});
32510 verifiedSig.verified.catch(() => {});
32511
32512 return verifiedSig;
32513}
32514
32515/**
32516 * Create list of objects containing signer's keyid and validity of signature
32517 * @param {Array<SignaturePacket>} signatureList - Array of signature packets
32518 * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
32519 * @param {Array<Key>} keys - Array of keys to verify signatures
32520 * @param {Date} date - Verify the signature against the given date,
32521 * i.e. check signature creation time < date < expiration time
32522 * @param {Boolean} [detached] - Whether to verify detached signature packets
32523 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32524 * @returns {Promise<Array<{keyid: module:type/keyid~Keyid,
32525 * valid: Boolean}>>} list of signer's keyid and validity of signature
32526 * @async
32527 * @private
32528 */
32529async function createVerificationObjects(signatureList, literalDataList, keys, date = new Date(), detached = false, streaming = false, config = defaultConfig) {
32530 return Promise.all(signatureList.filter(function(signature) {
32531 return ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType));
32532 }).map(async function(signature) {
32533 return createVerificationObject(signature, literalDataList, keys, date, detached, streaming, config);
32534 }));
32535}
32536
32537/**
32538 * Reads an (optionally armored) OpenPGP message and returns a Message object
32539 * @param {Object} options
32540 * @param {String | ReadableStream<String>} [options.armoredMessage] - Armored message to be parsed
32541 * @param {Uint8Array | ReadableStream<Uint8Array>} [options.binaryMessage] - Binary to be parsed
32542 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32543 * @returns {Message} New message object.
32544 * @async
32545 * @static
32546 */
32547async function readMessage({ armoredMessage, binaryMessage, config }) {
32548 config = { ...defaultConfig, ...config };
32549 let input = armoredMessage || binaryMessage;
32550 if (!input) {
32551 throw new Error('readMessage: must pass options object containing `armoredMessage` or `binaryMessage`');
32552 }
32553 const streamType = util.isStream(input);
32554 if (streamType === 'node') {
32555 input = stream.nodeToWeb(input);
32556 }
32557 if (armoredMessage) {
32558 const { type, data } = await unarmor(input, config);
32559 if (type !== enums.armor.message) {
32560 throw new Error('Armored text not of type message');
32561 }
32562 input = data;
32563 }
32564 const packetlist = new PacketList();
32565 await packetlist.read(input, {
32566 LiteralDataPacket,
32567 CompressedDataPacket,
32568 AEADEncryptedDataPacket,
32569 SymEncryptedIntegrityProtectedDataPacket,
32570 SymmetricallyEncryptedDataPacket,
32571 PublicKeyEncryptedSessionKeyPacket,
32572 SymEncryptedSessionKeyPacket,
32573 OnePassSignaturePacket,
32574 SignaturePacket
32575 }, streamType, config);
32576 const message = new Message(packetlist);
32577 message.fromStream = streamType;
32578 return message;
32579}
32580
32581// GPG4Browsers - An OpenPGP implementation in javascript
32582
32583/**
32584 * Class that represents an OpenPGP cleartext signed message.
32585 * See {@link https://tools.ietf.org/html/rfc4880#section-7}
32586 */
32587class CleartextMessage {
32588 /**
32589 * @param {String} text - The cleartext of the signed message
32590 * @param {Signature} signature - The detached signature or an empty signature for unsigned messages
32591 */
32592 constructor(text, signature) {
32593 // normalize EOL to canonical form <CR><LF>
32594 this.text = util.removeTrailingSpaces(text).replace(/\r?\n/g, '\r\n');
32595 if (signature && !(signature instanceof Signature)) {
32596 throw new Error('Invalid signature input');
32597 }
32598 this.signature = signature || new Signature(new PacketList());
32599 }
32600
32601 /**
32602 * Returns the key IDs of the keys that signed the cleartext message
32603 * @returns {Array<module:type/keyid~Keyid>} Array of keyid objects.
32604 */
32605 getSigningKeyIds() {
32606 const keyIds = [];
32607 const signatureList = this.signature.packets;
32608 signatureList.forEach(function(packet) {
32609 keyIds.push(packet.issuerKeyId);
32610 });
32611 return keyIds;
32612 }
32613
32614 /**
32615 * Sign the cleartext message
32616 * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
32617 * @param {Signature} [signature] - Any existing detached signature
32618 * @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i]
32619 * @param {Date} [date] - The creation time of the signature that should be created
32620 * @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
32621 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32622 * @returns {CleartextMessage} New cleartext message with signed content.
32623 * @async
32624 */
32625 async sign(privateKeys, signature = null, signingKeyIds = [], date = new Date(), userIds = [], config = defaultConfig) {
32626 return new CleartextMessage(this.text, await this.signDetached(privateKeys, signature, signingKeyIds, date, userIds, config));
32627 }
32628
32629 /**
32630 * Sign the cleartext message
32631 * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
32632 * @param {Signature} [signature] - Any existing detached signature
32633 * @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i]
32634 * @param {Date} [date] - The creation time of the signature that should be created
32635 * @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
32636 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32637 * @returns {Signature} New detached signature of message content.
32638 * @async
32639 */
32640 async signDetached(privateKeys, signature = null, signingKeyIds = [], date = new Date(), userIds = [], config = defaultConfig) {
32641 const literalDataPacket = new LiteralDataPacket();
32642 literalDataPacket.setText(this.text);
32643
32644 return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIds, true, undefined, config));
32645 }
32646
32647 /**
32648 * Verify signatures of cleartext signed message
32649 * @param {Array<Key>} keys - Array of keys to verify signatures
32650 * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
32651 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32652 * @returns {Array<{keyid: module:type/keyid~Keyid, valid: Boolean}>} List of signer's keyid and validity of signature.
32653 * @async
32654 */
32655 verify(keys, date = new Date(), config = defaultConfig) {
32656 return this.verifyDetached(this.signature, keys, date, config);
32657 }
32658
32659 /**
32660 * Verify signatures of cleartext signed message
32661 * @param {Array<Key>} keys - Array of keys to verify signatures
32662 * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
32663 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32664 * @returns {Array<{keyid: module:type/keyid~Keyid, valid: Boolean}>} List of signer's keyid and validity of signature.
32665 * @async
32666 */
32667 verifyDetached(signature, keys, date = new Date(), config = defaultConfig) {
32668 const signatureList = signature.packets;
32669 const literalDataPacket = new LiteralDataPacket();
32670 // we assume that cleartext signature is generated based on UTF8 cleartext
32671 literalDataPacket.setText(this.text);
32672 return createVerificationObjects(signatureList, [literalDataPacket], keys, date, true, undefined, config);
32673 }
32674
32675 /**
32676 * Get cleartext
32677 * @returns {String} Cleartext of message.
32678 */
32679 getText() {
32680 // normalize end of line to \n
32681 return this.text.replace(/\r\n/g, '\n');
32682 }
32683
32684 /**
32685 * Returns ASCII armored text of cleartext signed message
32686 * @param {Object} [config] - Full configuration, defaults to openpgp.config
32687 * @returns {String | ReadableStream<String>} ASCII armor.
32688 */
32689 armor(config = defaultConfig) {
32690 let hashes = this.signature.packets.map(function(packet) {
32691 return enums.read(enums.hash, packet.hashAlgorithm).toUpperCase();
32692 });
32693 hashes = hashes.filter(function(item, i, ar) { return ar.indexOf(item) === i; });
32694 const body = {
32695 hash: hashes.join(),
32696 text: this.text,
32697 data: this.signature.packets.write()
32698 };
32699 return armor(enums.armor.signed, body, undefined, undefined, undefined, config);
32700 }
32701
32702 /**
32703 * Creates a new CleartextMessage object from text
32704 * @param {String} text
32705 * @static
32706 */
32707 static fromText(text) {
32708 return new CleartextMessage(text);
32709 }
32710}
32711
32712
32713/**
32714 * Reads an OpenPGP cleartext signed message and returns a CleartextMessage object
32715 * @param {Object} options
32716 * @param {String | ReadableStream<String>} options.cleartextMessage - Text to be parsed
32717 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32718 * @returns {CleartextMessage} New cleartext message object.
32719 * @async
32720 * @static
32721 */
32722async function readCleartextMessage({ cleartextMessage, config }) {
32723 config = { ...defaultConfig, ...config };
32724 if (!cleartextMessage) {
32725 throw new Error('readCleartextMessage: must pass options object containing `cleartextMessage`');
32726 }
32727 const input = await unarmor(cleartextMessage);
32728 if (input.type !== enums.armor.signed) {
32729 throw new Error('No cleartext signed message.');
32730 }
32731 const packetlist = new PacketList();
32732 await packetlist.read(input.data, { SignaturePacket }, undefined, config);
32733 verifyHeaders$1(input.headers, packetlist);
32734 const signature = new Signature(packetlist);
32735 return new CleartextMessage(input.text, signature);
32736}
32737
32738/**
32739 * Compare hash algorithm specified in the armor header with signatures
32740 * @param {Array<String>} headers - Armor headers
32741 * @param {PacketList} packetlist - The packetlist with signature packets
32742 * @private
32743 */
32744function verifyHeaders$1(headers, packetlist) {
32745 const checkHashAlgos = function(hashAlgos) {
32746 const check = packet => algo => packet.hashAlgorithm === algo;
32747
32748 for (let i = 0; i < packetlist.length; i++) {
32749 if (packetlist[i].tag === enums.packet.signature && !hashAlgos.some(check(packetlist[i]))) {
32750 return false;
32751 }
32752 }
32753 return true;
32754 };
32755
32756 let oneHeader = null;
32757 let hashAlgos = [];
32758 headers.forEach(function(header) {
32759 oneHeader = header.match(/Hash: (.+)/); // get header value
32760 if (oneHeader) {
32761 oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
32762 oneHeader = oneHeader.split(',');
32763 oneHeader = oneHeader.map(function(hash) {
32764 hash = hash.toLowerCase();
32765 try {
32766 return enums.write(enums.hash, hash);
32767 } catch (e) {
32768 throw new Error('Unknown hash algorithm in armor header: ' + hash);
32769 }
32770 });
32771 hashAlgos = hashAlgos.concat(oneHeader);
32772 } else {
32773 throw new Error('Only "Hash" header allowed in cleartext signed message');
32774 }
32775 });
32776
32777 if (!hashAlgos.length && !checkHashAlgos([enums.hash.md5])) {
32778 throw new Error('If no "Hash" header in cleartext signed message, then only MD5 signatures allowed');
32779 } else if (hashAlgos.length && !checkHashAlgos(hashAlgos)) {
32780 throw new Error('Hash algorithm mismatch in armor header and signature');
32781 }
32782}
32783
32784// OpenPGP.js - An OpenPGP implementation in javascript
32785
32786let toNativeReadable;
32787if (globalThis.ReadableStream) {
32788 try {
32789 toNativeReadable = createReadableStreamWrapper(globalThis.ReadableStream);
32790 } catch (e) {}
32791}
32792
32793//////////////////////
32794// //
32795// Key handling //
32796// //
32797//////////////////////
32798
32799
32800/**
32801 * Generates a new OpenPGP key pair. Supports RSA and ECC keys. By default, primary and subkeys will be of same type.
32802 * @param {Object} options
32803 * @param {'ecc'|'rsa'} [options.type='ecc'] - The primary key algorithm type: ECC (default) or RSA
32804 * @param {Object|Array<Object>} options.userIds - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
32805 * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key
32806 * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys
32807 * @param {String} [options.curve='curve25519'] - Elliptic curve for ECC keys:
32808 * curve25519 (default), p256, p384, p521, secp256k1,
32809 * brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1
32810 * @param {Date} [options.date=current date] - Override the creation date of the key and the key signatures
32811 * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires
32812 * @param {Array<Object>} [options.subkeys=a single encryption subkey] - Options for each subkey, default to main key options. e.g. `[{sign: true, passphrase: '123'}]`
32813 * sign parameter defaults to false, and indicates whether the subkey should sign rather than encrypt
32814 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32815 * @returns {Object} The generated key object in the form:
32816 * { key:Key, privateKeyArmored:String, publicKeyArmored:String, revocationCertificate:String }
32817 * @async
32818 * @static
32819 */
32820function generateKey({ userIds = [], passphrase = "", type = "ecc", rsaBits = 4096, curve = "curve25519", keyExpirationTime = 0, date = new Date(), subkeys = [{}], config }) {
32821 config = { ...defaultConfig, ...config };
32822 userIds = toArray$1(userIds);
32823 const options = { userIds, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys };
32824 if (type === "rsa" && rsaBits < config.minRsaBits) {
32825 throw new Error(`rsaBits should be at least ${config.minRsaBits}, got: ${rsaBits}`);
32826 }
32827
32828 return generate$2(options, config).then(async key => {
32829 const revocationCertificate = await key.getRevocationCertificate(date, config);
32830 key.revocationSignatures = [];
32831
32832 return {
32833
32834 key: key,
32835 privateKeyArmored: key.armor(config),
32836 publicKeyArmored: key.toPublic().armor(config),
32837 revocationCertificate: revocationCertificate
32838
32839 };
32840 }).catch(onError.bind(null, 'Error generating keypair'));
32841}
32842
32843/**
32844 * Reformats signature packets for a key and rewraps key object.
32845 * @param {Object} options
32846 * @param {Key} options.privateKey - Private key to reformat
32847 * @param {Object|Array<Object>} options.userIds - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
32848 * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key
32849 * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires
32850 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32851 * @returns {Object} The generated key object in the form:
32852 * { key:Key, privateKeyArmored:String, publicKeyArmored:String, revocationCertificate:String }
32853 * @async
32854 * @static
32855 */
32856function reformatKey({ privateKey, userIds = [], passphrase = "", keyExpirationTime = 0, date, config }) {
32857 config = { ...defaultConfig, ...config };
32858 userIds = toArray$1(userIds);
32859 const options = { privateKey, userIds, passphrase, keyExpirationTime, date };
32860
32861 return reformat(options, config).then(async key => {
32862 const revocationCertificate = await key.getRevocationCertificate(date, config);
32863 key.revocationSignatures = [];
32864
32865 return {
32866
32867 key: key,
32868 privateKeyArmored: key.armor(config),
32869 publicKeyArmored: key.toPublic().armor(config),
32870 revocationCertificate: revocationCertificate
32871
32872 };
32873 }).catch(onError.bind(null, 'Error reformatting keypair'));
32874}
32875
32876/**
32877 * Revokes a key. Requires either a private key or a revocation certificate.
32878 * If a revocation certificate is passed, the reasonForRevocation parameter will be ignored.
32879 * @param {Object} options
32880 * @param {Key} options.key - Public or private key to revoke
32881 * @param {String} [options.revocationCertificate] - Revocation certificate to revoke the key with
32882 * @param {Object} [options.reasonForRevocation] - Object indicating the reason for revocation
32883 * @param {module:enums.reasonForRevocation} [options.reasonForRevocation.flag=[noReason]{@link module:enums.reasonForRevocation}] - Flag indicating the reason for revocation
32884 * @param {String} [options.reasonForRevocation.string=""] - String explaining the reason for revocation
32885 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32886 * @returns {Object} The revoked key object in the form:
32887 * `{ privateKey:Key, privateKeyArmored:String, publicKey:Key, publicKeyArmored:String }`
32888 * (if private key is passed) or `{ publicKey:Key, publicKeyArmored:String }` (otherwise)
32889 * @async
32890 * @static
32891 */
32892function revokeKey({ key, revocationCertificate, reasonForRevocation, config }) {
32893 config = { ...defaultConfig, ...config };
32894 return Promise.resolve().then(() => {
32895 if (revocationCertificate) {
32896 return key.applyRevocationCertificate(revocationCertificate, config);
32897 } else {
32898 return key.revoke(reasonForRevocation, undefined, config);
32899 }
32900 }).then(async key => {
32901 if (key.isPrivate()) {
32902 const publicKey = key.toPublic();
32903 return {
32904 privateKey: key,
32905 privateKeyArmored: key.armor(config),
32906 publicKey: publicKey,
32907 publicKeyArmored: publicKey.armor(config)
32908 };
32909 }
32910 return {
32911 publicKey: key,
32912 publicKeyArmored: key.armor(config)
32913 };
32914 }).catch(onError.bind(null, 'Error revoking key'));
32915}
32916
32917/**
32918 * Unlock a private key with the given passphrase.
32919 * This method does not change the original key.
32920 * @param {Object} options
32921 * @param {Key} options.privateKey - The private key to decrypt
32922 * @param {String|Array<String>} options.passphrase - The user's passphrase(s)
32923 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32924 * @returns {Key} The unlocked key object.
32925 * @async
32926 */
32927async function decryptKey({ privateKey, passphrase, config }) {
32928 config = { ...defaultConfig, ...config };
32929 const key = await privateKey.clone();
32930 // shallow clone is enough since the encrypted material is not changed in place by decryption
32931 key.getKeys().forEach(k => {
32932 k.keyPacket = Object.create(
32933 Object.getPrototypeOf(k.keyPacket),
32934 Object.getOwnPropertyDescriptors(k.keyPacket)
32935 );
32936 });
32937 try {
32938 await key.decrypt(passphrase, undefined, config);
32939 return key;
32940 } catch (err) {
32941 key.clearPrivateParams();
32942 return onError('Error decrypting private key', err);
32943 }
32944}
32945
32946/**
32947 * Lock a private key with the given passphrase.
32948 * This method does not change the original key.
32949 * @param {Object} options
32950 * @param {Key} options.privateKey - The private key to encrypt
32951 * @param {String|Array<String>} options.passphrase - If multiple passphrases, they should be in the same order as the packets each should encrypt
32952 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
32953 * @returns {Key} The locked key object.
32954 * @async
32955 */
32956async function encryptKey({ privateKey, passphrase, config }) {
32957 config = { ...defaultConfig, ...config };
32958 const key = await privateKey.clone();
32959 key.getKeys().forEach(k => {
32960 // shallow clone the key packets
32961 k.keyPacket = Object.create(
32962 Object.getPrototypeOf(k.keyPacket),
32963 Object.getOwnPropertyDescriptors(k.keyPacket)
32964 );
32965 if (!k.keyPacket.isDecrypted()) return;
32966 // deep clone the private params, which are cleared during encryption
32967 const privateParams = {};
32968 Object.keys(k.keyPacket.privateParams).forEach(name => {
32969 privateParams[name] = new Uint8Array(k.keyPacket.privateParams[name]);
32970 });
32971 k.keyPacket.privateParams = privateParams;
32972 });
32973 try {
32974 await key.encrypt(passphrase, undefined, config);
32975 return key;
32976 } catch (err) {
32977 key.clearPrivateParams();
32978 return onError('Error encrypting private key', err);
32979 }
32980}
32981
32982
32983///////////////////////////////////////////
32984// //
32985// Message encryption and decryption //
32986// //
32987///////////////////////////////////////////
32988
32989
32990/**
32991 * Encrypts message text/data with public keys, passwords or both at once. At least either public keys or passwords
32992 * must be specified. If private keys are specified, those will be used to sign the message.
32993 * @param {Object} options
32994 * @param {Message} options.message - Message to be encrypted as created by {@link Message.fromText} or {@link Message.fromBinary}
32995 * @param {Key|Array<Key>} [options.publicKeys] - Array of keys or single key, used to encrypt the message
32996 * @param {Key|Array<Key>} [options.privateKeys] - Private keys for signing. If omitted message will not be signed
32997 * @param {String|Array<String>} [options.passwords] - Array of passwords or a single password to encrypt the message
32998 * @param {Object} [options.sessionKey] - Session key in the form: `{ data:Uint8Array, algorithm:String }`
32999 * @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false)
33000 * @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream
33001 * @param {Signature} [options.signature] - A detached signature to add to the encrypted message
33002 * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
33003 * @param {Array<module:type/keyid~Keyid>} [options.signingKeyIds=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each `signingKeyIds[i]` corresponds to `privateKeys[i]`
33004 * @param {Array<module:type/keyid~Keyid>} [options.encryptionKeyIds=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each `encryptionKeyIds[i]` corresponds to `publicKeys[i]`
33005 * @param {Date} [options.date=current date] - Override the creation date of the message signature
33006 * @param {Array<Object>} [options.fromUserIds=primary user IDs] - Array of user IDs to sign with, one per key in `privateKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
33007 * @param {Array<Object>} [options.toUserIds=primary user IDs] - Array of user IDs to encrypt for, one per key in `publicKeys`, e.g. `[{ name: 'Robert Receiver', email: 'robert@openpgp.org' }]`
33008 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33009 * @returns {String|ReadableStream<String>|NodeStream<String>|Uint8Array|ReadableStream<Uint8Array>|NodeStream<Uint8Array>} Encrypted message (string if `armor` was true, the default; Uint8Array if `armor` was false).
33010 * @async
33011 * @static
33012 */
33013function encrypt$4({ message, publicKeys, privateKeys, passwords, sessionKey, armor = true, streaming = message && message.fromStream, detached = false, signature = null, wildcard = false, signingKeyIds = [], encryptionKeyIds = [], date = new Date(), fromUserIds = [], toUserIds = [], config }) {
33014 config = { ...defaultConfig, ...config };
33015 checkMessage(message); publicKeys = toArray$1(publicKeys); privateKeys = toArray$1(privateKeys); passwords = toArray$1(passwords); fromUserIds = toArray$1(fromUserIds); toUserIds = toArray$1(toUserIds);
33016 if (detached) {
33017 throw new Error("detached option has been removed from openpgp.encrypt. Separately call openpgp.sign instead. Don't forget to remove privateKeys option as well.");
33018 }
33019
33020 return Promise.resolve().then(async function() {
33021 if (!privateKeys) {
33022 privateKeys = [];
33023 }
33024 if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified
33025 message = await message.sign(privateKeys, signature, signingKeyIds, date, fromUserIds, message.fromStream, config);
33026 }
33027 message = message.compress(config);
33028 message = await message.encrypt(publicKeys, passwords, sessionKey, wildcard, encryptionKeyIds, date, toUserIds, streaming, config);
33029 const data = armor ? message.armor(config) : message.write();
33030 return convertStream(data, streaming, armor ? 'utf8' : 'binary');
33031 }).catch(onError.bind(null, 'Error encrypting message'));
33032}
33033
33034/**
33035 * Decrypts a message with the user's private key, a session key or a password. Either a private key,
33036 * a session key or a password must be specified.
33037 * @param {Object} options
33038 * @param {Message} options.message - The message object with the encrypted data
33039 * @param {Key|Array<Key>} [options.privateKeys] - Private keys with decrypted secret key data or session key
33040 * @param {String|Array<String>} [options.passwords] - Passwords to decrypt the message
33041 * @param {Object|Array<Object>} [options.sessionKeys] - Session keys in the form: { data:Uint8Array, algorithm:String }
33042 * @param {Key|Array<Key>} [options.publicKeys] - Array of public keys or single key, to verify signatures
33043 * @param {'utf8'|'binary'} [options.format='utf8'] - Whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
33044 * @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
33045 * @param {Signature} [options.signature] - Detached signature for verification
33046 * @param {Date} [options.date=current date] - Use the given date for verification instead of the current time
33047 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33048 * @returns {Object} Object containing decrypted and verified message in the form:
33049 *
33050 * {
33051 * data: String|ReadableStream<String>|NodeStream, (if format was 'utf8', the default)
33052 * data: Uint8Array|ReadableStream<Uint8Array>|NodeStream, (if format was 'binary')
33053 * filename: String,
33054 * signatures: [
33055 * {
33056 * keyid: module:type/keyid~Keyid,
33057 * verified: Promise<Boolean>,
33058 * valid: Boolean (if streaming was false)
33059 * }, ...
33060 * ]
33061 * }
33062 * @async
33063 * @static
33064 */
33065function decrypt$4({ message, privateKeys, passwords, sessionKeys, publicKeys, format = 'utf8', streaming = message && message.fromStream, signature = null, date = new Date(), config }) {
33066 config = { ...defaultConfig, ...config };
33067 checkMessage(message); publicKeys = toArray$1(publicKeys); privateKeys = toArray$1(privateKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
33068
33069 return message.decrypt(privateKeys, passwords, sessionKeys, streaming, config).then(async function(decrypted) {
33070 if (!publicKeys) {
33071 publicKeys = [];
33072 }
33073
33074 const result = {};
33075 result.signatures = signature ? await decrypted.verifyDetached(signature, publicKeys, date, streaming, config) : await decrypted.verify(publicKeys, date, streaming, config);
33076 result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
33077 result.filename = decrypted.getFilename();
33078 linkStreams(result, message);
33079 result.data = await convertStream(result.data, streaming, format);
33080 if (!streaming) await prepareSignatures(result.signatures);
33081 return result;
33082 }).catch(onError.bind(null, 'Error decrypting message'));
33083}
33084
33085
33086//////////////////////////////////////////
33087// //
33088// Message signing and verification //
33089// //
33090//////////////////////////////////////////
33091
33092
33093/**
33094 * Signs a message.
33095 * @param {Object} options
33096 * @param {CleartextMessage|Message} options.message - (cleartext) message to be signed
33097 * @param {Key|Array<Key>} options.privateKeys - Array of keys or single key with decrypted secret key data to sign cleartext
33098 * @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false)
33099 * @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
33100 * @param {Boolean} [options.detached=false] - If the return value should contain a detached signature
33101 * @param {Array<module:type/keyid~Keyid>} [options.signingKeyIds=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i]
33102 * @param {Date} [options.date=current date] - Override the creation date of the signature
33103 * @param {Array<Object>} [options.fromUserIds=primary user IDs] - Array of user IDs to sign with, one per key in `privateKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
33104 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33105 * @returns {String|ReadableStream<String>|NodeStream<String>|Uint8Array|ReadableStream<Uint8Array>|NodeStream<Uint8Array>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false).
33106 * @async
33107 * @static
33108 */
33109function sign$5({ message, privateKeys, armor = true, streaming = message && message.fromStream, detached = false, signingKeyIds = [], date = new Date(), fromUserIds = [], config }) {
33110 config = { ...defaultConfig, ...config };
33111 checkCleartextOrMessage(message);
33112 if (message instanceof CleartextMessage && !armor) throw new Error("Can't sign non-armored cleartext message");
33113 if (message instanceof CleartextMessage && detached) throw new Error("Can't sign detached cleartext message");
33114 privateKeys = toArray$1(privateKeys); fromUserIds = toArray$1(fromUserIds);
33115
33116 return Promise.resolve().then(async function() {
33117 let signature;
33118 if (message instanceof CleartextMessage) {
33119 signature = await message.sign(privateKeys, undefined, signingKeyIds, date, fromUserIds, config);
33120 } else if (detached) {
33121 signature = await message.signDetached(privateKeys, undefined, signingKeyIds, date, fromUserIds, message.fromStream, config);
33122 } else {
33123 signature = await message.sign(privateKeys, undefined, signingKeyIds, date, fromUserIds, message.fromStream, config);
33124 }
33125 signature = armor ? signature.armor(config) : signature.write();
33126 if (detached) {
33127 signature = stream.transformPair(message.packets.write(), async (readable, writable) => {
33128 await Promise.all([
33129 stream.pipe(signature, writable),
33130 stream.readToEnd(readable).catch(() => {})
33131 ]);
33132 });
33133 }
33134 return convertStream(signature, streaming, armor ? 'utf8' : 'binary');
33135 }).catch(onError.bind(null, 'Error signing message'));
33136}
33137
33138/**
33139 * Verifies signatures of cleartext signed message
33140 * @param {Object} options
33141 * @param {Key|Array<Key>} options.publicKeys - Array of publicKeys or single key, to verify signatures
33142 * @param {CleartextMessage|Message} options.message - (cleartext) message object with signatures
33143 * @param {'utf8'|'binary'} [options.format='utf8'] - Whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
33144 * @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
33145 * @param {Signature} [options.signature] - Detached signature for verification
33146 * @param {Date} [options.date=current date] - Use the given date for verification instead of the current time
33147 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33148 * @returns {Object} Object containing verified message in the form:
33149 *
33150 * {
33151 * data: String|ReadableStream<String>|NodeStream, (if `message` was a CleartextMessage)
33152 * data: Uint8Array|ReadableStream<Uint8Array>|NodeStream, (if `message` was a Message)
33153 * signatures: [
33154 * {
33155 * keyid: module:type/keyid~Keyid,
33156 * verified: Promise<Boolean>,
33157 * valid: Boolean (if `streaming` was false)
33158 * }, ...
33159 * ]
33160 * }
33161 * @async
33162 * @static
33163 */
33164function verify$5({ message, publicKeys, format = 'utf8', streaming = message && message.fromStream, signature = null, date = new Date(), config }) {
33165 config = { ...defaultConfig, ...config };
33166 checkCleartextOrMessage(message);
33167 if (message instanceof CleartextMessage && format === 'binary') throw new Error("Can't return cleartext message data as binary");
33168 publicKeys = toArray$1(publicKeys);
33169
33170 return Promise.resolve().then(async function() {
33171 const result = {};
33172 if (message instanceof CleartextMessage) {
33173 result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date, config) : await message.verify(publicKeys, date, config);
33174 } else {
33175 result.signatures = signature ? await message.verifyDetached(signature, publicKeys, date, streaming, config) : await message.verify(publicKeys, date, streaming, config);
33176 }
33177 result.data = format === 'binary' ? message.getLiteralData() : message.getText();
33178 if (streaming) linkStreams(result, message);
33179 result.data = await convertStream(result.data, streaming, format);
33180 if (!streaming) await prepareSignatures(result.signatures);
33181 return result;
33182 }).catch(onError.bind(null, 'Error verifying signed message'));
33183}
33184
33185
33186///////////////////////////////////////////////
33187// //
33188// Session key encryption and decryption //
33189// //
33190///////////////////////////////////////////////
33191
33192/**
33193 * Generate a new session key object, taking the algorithm preferences of the passed public keys into account.
33194 * @param {Object} options
33195 * @param {Key|Array<Key>} options.publicKeys - Array of public keys or single key used to select algorithm preferences for
33196 * @param {Date} [options.date=current date] - Date to select algorithm preferences at
33197 * @param {Array} [options.toUserIds=primary user IDs] - User IDs to select algorithm preferences for
33198 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33199 * @returns {{ data: Uint8Array, algorithm: String }} Object with session key data and algorithm.
33200 * @async
33201 * @static
33202 */
33203function generateSessionKey$1({ publicKeys, date = new Date(), toUserIds = [], config }) {
33204 config = { ...defaultConfig, ...config };
33205 publicKeys = toArray$1(publicKeys); toUserIds = toArray$1(toUserIds);
33206
33207 return Promise.resolve().then(async function() {
33208
33209 return Message.generateSessionKey(publicKeys, date, toUserIds, config);
33210
33211 }).catch(onError.bind(null, 'Error generating session key'));
33212}
33213
33214/**
33215 * Encrypt a symmetric session key with public keys, passwords, or both at once. At least either public keys
33216 * or passwords must be specified.
33217 * @param {Object} options
33218 * @param {Uint8Array} options.data - The session key to be encrypted e.g. 16 random bytes (for aes128)
33219 * @param {String} options.algorithm - Algorithm of the symmetric session key e.g. 'aes128' or 'aes256'
33220 * @param {String} [options.aeadAlgorithm] - Aead algorithm, e.g. 'eax' or 'ocb'
33221 * @param {Key|Array<Key>} [options.publicKeys] - Array of public keys or single key, used to encrypt the key
33222 * @param {String|Array<String>} [options.passwords] - Passwords for the message
33223 * @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false)
33224 * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
33225 * @param {Array<module:type/keyid~Keyid>} [options.encryptionKeyIds=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each encryptionKeyIds[i] corresponds to publicKeys[i]
33226 * @param {Date} [options.date=current date] - Override the date
33227 * @param {Array} [options.toUserIds=primary user IDs] - Array of user IDs to encrypt for, one per key in `publicKeys`, e.g. `[{ name: 'Phil Zimmermann', email: 'phil@openpgp.org' }]`
33228 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33229 * @returns {String|Uint8Array} Encrypted session keys (string if `armor` was true, the default; Uint8Array if `armor` was false).
33230 * @async
33231 * @static
33232 */
33233function encryptSessionKey({ data, algorithm, aeadAlgorithm, publicKeys, passwords, armor = true, wildcard = false, encryptionKeyIds = [], date = new Date(), toUserIds = [], config }) {
33234 config = { ...defaultConfig, ...config };
33235 checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray$1(publicKeys); passwords = toArray$1(passwords); toUserIds = toArray$1(toUserIds);
33236
33237 return Promise.resolve().then(async function() {
33238
33239 const message = await Message.encryptSessionKey(data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, encryptionKeyIds, date, toUserIds, config);
33240 return armor ? message.armor(config) : message.write();
33241
33242 }).catch(onError.bind(null, 'Error encrypting session key'));
33243}
33244
33245/**
33246 * Decrypt symmetric session keys with a private key or password. Either a private key or
33247 * a password must be specified.
33248 * @param {Object} options
33249 * @param {Message} options.message - A message object containing the encrypted session key packets
33250 * @param {Key|Array<Key>} [options.privateKeys] - Private keys with decrypted secret key data
33251 * @param {String|Array<String>} [options.passwords] - Passwords to decrypt the session key
33252 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
33253 * @returns {Object|undefined} Array of decrypted session key, algorithm pairs in the form:
33254 * { data:Uint8Array, algorithm:String }
33255 * or 'undefined' if no key packets found
33256 * @async
33257 * @static
33258 */
33259function decryptSessionKeys({ message, privateKeys, passwords, config }) {
33260 config = { ...defaultConfig, ...config };
33261 checkMessage(message); privateKeys = toArray$1(privateKeys); passwords = toArray$1(passwords);
33262
33263 return Promise.resolve().then(async function() {
33264
33265 return message.decryptSessionKeys(privateKeys, passwords, config);
33266
33267 }).catch(onError.bind(null, 'Error decrypting session keys'));
33268}
33269
33270
33271//////////////////////////
33272// //
33273// Helper functions //
33274// //
33275//////////////////////////
33276
33277
33278/**
33279 * Input validation
33280 * @private
33281 */
33282function checkString(data, name) {
33283 if (!util.isString(data)) {
33284 throw new Error('Parameter [' + (name || 'data') + '] must be of type String');
33285 }
33286}
33287function checkBinary(data, name) {
33288 if (!util.isUint8Array(data)) {
33289 throw new Error('Parameter [' + (name || 'data') + '] must be of type Uint8Array');
33290 }
33291}
33292function checkMessage(message) {
33293 if (!(message instanceof Message)) {
33294 throw new Error('Parameter [message] needs to be of type Message');
33295 }
33296}
33297function checkCleartextOrMessage(message) {
33298 if (!(message instanceof CleartextMessage) && !(message instanceof Message)) {
33299 throw new Error('Parameter [message] needs to be of type Message or CleartextMessage');
33300 }
33301}
33302
33303/**
33304 * Normalize parameter to an array if it is not undefined.
33305 * @param {Object} param - the parameter to be normalized
33306 * @returns {Array<Object>|undefined} The resulting array or undefined.
33307 * @private
33308 */
33309function toArray$1(param) {
33310 if (param && !util.isArray(param)) {
33311 param = [param];
33312 }
33313 return param;
33314}
33315
33316/**
33317 * Convert data to or from Stream
33318 * @param {Object} data - the data to convert
33319 * @param {'web'|'ponyfill'|'node'|false} [options.streaming] - Whether to return a ReadableStream, and of what type
33320 * @param {'utf8'|'binary'} [options.encoding] - How to return data in Node Readable streams
33321 * @returns {Object} The data in the respective format.
33322 * @private
33323 */
33324async function convertStream(data, streaming, encoding = 'utf8') {
33325 let streamType = util.isStream(data);
33326 if (!streaming && streamType) {
33327 return stream.readToEnd(data);
33328 }
33329 if (streaming && !streamType) {
33330 data = stream.toStream(data);
33331 streamType = util.isStream(data);
33332 }
33333 if (streaming === 'node') {
33334 data = stream.webToNode(data);
33335 if (encoding !== 'binary') data.setEncoding(encoding);
33336 return data;
33337 }
33338 if (streaming === 'web' && streamType === 'ponyfill' && toNativeReadable) {
33339 return toNativeReadable(data);
33340 }
33341 return data;
33342}
33343
33344/**
33345 * Link result.data to the message stream for cancellation.
33346 * Also, forward errors in the message to result.data.
33347 * @param {Object} result - the data to convert
33348 * @param {Message} message - message object
33349 * @returns {Object}
33350 * @private
33351 */
33352function linkStreams(result, message) {
33353 result.data = stream.transformPair(message.packets.stream, async (readable, writable) => {
33354 await stream.pipe(result.data, writable, {
33355 preventClose: true
33356 });
33357 const writer = stream.getWriter(writable);
33358 try {
33359 // Forward errors in the message stream to result.data.
33360 await stream.readToEnd(readable, _ => _);
33361 await writer.close();
33362 } catch (e) {
33363 await writer.abort(e);
33364 }
33365 });
33366}
33367
33368/**
33369 * Wait until signature objects have been verified
33370 * @param {Object} signatures - list of signatures
33371 * @private
33372 */
33373async function prepareSignatures(signatures) {
33374 await Promise.all(signatures.map(async signature => {
33375 signature.signature = await signature.signature;
33376 try {
33377 signature.valid = await signature.verified;
33378 } catch (e) {
33379 signature.valid = false;
33380 signature.error = e;
33381 util.printDebugError(e);
33382 }
33383 }));
33384}
33385
33386
33387/**
33388 * Global error handler that logs the stack trace and rethrows a high lvl error message.
33389 * @param {String} message - A human readable high level error Message
33390 * @param {Error} error - The internal error that caused the failure
33391 * @private
33392 */
33393function onError(message, error) {
33394 // log the stack trace
33395 util.printDebugError(error);
33396
33397 // update error message
33398 try {
33399 error.message = message + ': ' + error.message;
33400 } catch (e) {}
33401
33402 throw error;
33403}
33404
33405export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, Key, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UserAttributePacket, UserIDPacket, _224 as _, commonjsGlobal as a, armor, common$1 as b, createCommonjsModule as c, defaultConfig as config, common as d, decrypt$4 as decrypt, decryptKey, decryptSessionKeys, _256 as e, encrypt$4 as encrypt, encryptKey, encryptSessionKey, enums, _384 as f, _512 as g, generateKey, generateSessionKey$1 as generateSessionKey, inherits_browser as i, minimalisticAssert as m, newPacketFromTag, ripemd as r, readCleartextMessage, readKey, readKeys, readMessage, readSignature, reformatKey, revokeKey, sign$5 as sign, stream, utils as u, unarmor, verify$5 as verify };