@mpoonuru/paseto
Version:
Modern PASETO (Platform-Agnostic Security Tokens) for Node.js with TypeScript support and V4 LOCAL encryption
1,682 lines (1,665 loc) • 66.8 kB
JavaScript
// src/types/errors.ts
var PasetoError = class extends Error {
constructor(message, options) {
super(message, options);
this.name = "PasetoError";
}
};
var PasetoClaimInvalid = class extends PasetoError {
constructor(message, options) {
super(message, options);
this.name = "PasetoClaimInvalid";
}
};
var PasetoDecryptionFailed = class extends PasetoError {
constructor(message = "decryption failed", options) {
super(message, options);
this.name = "PasetoDecryptionFailed";
}
};
var PasetoInvalid = class extends PasetoError {
constructor(message, options) {
super(message, options);
this.name = "PasetoInvalid";
}
};
var PasetoNotSupported = class extends PasetoError {
constructor(message, options) {
super(message, options);
this.name = "PasetoNotSupported";
}
};
var PasetoVerificationFailed = class extends PasetoError {
constructor(message = "verification failed", options) {
super(message, options);
this.name = "PasetoVerificationFailed";
}
};
var errors = {
PasetoError,
PasetoClaimInvalid,
PasetoDecryptionFailed,
PasetoInvalid,
PasetoNotSupported,
PasetoVerificationFailed
};
// node_modules/@stablelib/random/lib/source/system.js
var QUOTA = 65536;
var SystemRandomSource = class {
isAvailable = false;
isInstantiated = false;
constructor() {
if (typeof crypto !== "undefined" && "getRandomValues" in crypto) {
this.isAvailable = true;
this.isInstantiated = true;
}
}
randomBytes(length) {
if (!this.isAvailable) {
throw new Error("System random byte generator is not available.");
}
const out = new Uint8Array(length);
for (let i = 0; i < out.length; i += QUOTA) {
crypto.getRandomValues(out.subarray(i, i + Math.min(out.length - i, QUOTA)));
}
return out;
}
};
// node_modules/@stablelib/int/lib/int.js
var isInteger = Number.isInteger;
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
var isSafeInteger = Number.isSafeInteger;
// node_modules/@stablelib/binary/lib/binary.js
function readUint32LE(array, offset = 0) {
return (array[offset + 3] << 24 | array[offset + 2] << 16 | array[offset + 1] << 8 | array[offset]) >>> 0;
}
function writeUint32LE(value, out = new Uint8Array(4), offset = 0) {
out[offset + 0] = value >>> 0;
out[offset + 1] = value >>> 8;
out[offset + 2] = value >>> 16;
out[offset + 3] = value >>> 24;
return out;
}
function writeUint64LE(value, out = new Uint8Array(8), offset = 0) {
writeUint32LE(value >>> 0, out, offset);
writeUint32LE(value / 4294967296 >>> 0, out, offset + 4);
return out;
}
// node_modules/@stablelib/wipe/lib/wipe.js
function wipe(array) {
for (let i = 0; i < array.length; i++) {
array[i] = 0;
}
return array;
}
// node_modules/@stablelib/random/lib/random.js
var defaultRandomSource = new SystemRandomSource();
function randomBytes(length, prng = defaultRandomSource) {
return prng.randomBytes(length);
}
// node_modules/@stablelib/blake2b/lib/blake2b.js
var BLOCK_SIZE = 128;
var DIGEST_LENGTH = 64;
var KEY_LENGTH = 64;
var PERSONALIZATION_LENGTH = 16;
var SALT_LENGTH = 16;
var MAX_LEAF_SIZE = Math.pow(2, 32) - 1;
var MAX_FANOUT = 255;
var MAX_MAX_DEPTH = 255;
var IV = new Uint32Array([
// low bits // high bits
4089235720,
1779033703,
2227873595,
3144134277,
4271175723,
1013904242,
1595750129,
2773480762,
2917565137,
1359893119,
725511199,
2600822924,
4215389547,
528734635,
327033209,
1541459225
]);
var SIGMA = [
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30],
[28, 20, 8, 16, 18, 30, 26, 12, 2, 24, 0, 4, 22, 14, 10, 6],
[22, 16, 24, 0, 10, 4, 30, 26, 20, 28, 6, 12, 14, 2, 18, 8],
[14, 18, 6, 2, 26, 24, 22, 28, 4, 12, 10, 20, 8, 0, 30, 16],
[18, 0, 10, 14, 4, 8, 20, 30, 28, 2, 22, 24, 12, 16, 6, 26],
[4, 24, 12, 20, 0, 22, 16, 6, 8, 26, 14, 10, 30, 28, 2, 18],
[24, 10, 2, 30, 28, 26, 8, 20, 0, 14, 12, 6, 18, 4, 16, 22],
[26, 22, 14, 28, 24, 2, 6, 18, 10, 0, 30, 8, 16, 12, 4, 20],
[12, 30, 28, 18, 22, 6, 0, 16, 24, 4, 26, 14, 2, 8, 20, 10],
[20, 4, 16, 8, 14, 12, 2, 10, 30, 22, 18, 28, 6, 24, 26, 0],
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30],
[28, 20, 8, 16, 18, 30, 26, 12, 2, 24, 0, 4, 22, 14, 10, 6]
];
var BLAKE2b = class {
digestLength;
blockSize = BLOCK_SIZE;
// Note: Int32Arrays for state and message are used for performance reasons.
_state = new Int32Array(IV);
// hash state, initialized with IV
_buffer = new Uint8Array(BLOCK_SIZE);
// buffer for data
_bufferLength = 0;
// number of bytes in buffer
_ctr = new Uint32Array(4);
_flag = new Uint32Array(4);
_lastNode = false;
_finished = false;
_vtmp = new Uint32Array(32);
_mtmp = new Uint32Array(32);
_paddedKey;
// copy of zero-padded key if present
_initialState;
// initial state after initialization
constructor(digestLength = 64, config) {
this.digestLength = digestLength;
if (digestLength < 1 || digestLength > DIGEST_LENGTH) {
throw new Error("blake2b: wrong digest length");
}
if (config) {
this.validateConfig(config);
}
let keyLength = 0;
if (config && config.key) {
keyLength = config.key.length;
}
let fanout = 1;
let maxDepth = 1;
if (config && config.tree) {
fanout = config.tree.fanout;
maxDepth = config.tree.maxDepth;
}
this._state[0] ^= digestLength | keyLength << 8 | fanout << 16 | maxDepth << 24;
if (config && config.tree) {
this._state[1] ^= config.tree.leafSize;
this._state[2] ^= config.tree.nodeOffsetLowBits;
this._state[3] ^= config.tree.nodeOffsetHighBits;
this._state[4] ^= config.tree.nodeDepth | config.tree.innerDigestLength << 8;
this._lastNode = config.tree.lastNode;
}
if (config && config.salt) {
this._state[8] ^= readUint32LE(config.salt, 0);
this._state[9] ^= readUint32LE(config.salt, 4);
this._state[10] ^= readUint32LE(config.salt, 8);
this._state[11] ^= readUint32LE(config.salt, 12);
}
if (config && config.personalization) {
this._state[12] ^= readUint32LE(config.personalization, 0);
this._state[13] ^= readUint32LE(config.personalization, 4);
this._state[14] ^= readUint32LE(config.personalization, 8);
this._state[15] ^= readUint32LE(config.personalization, 12);
}
this._initialState = new Uint32Array(this._state);
if (config && config.key && keyLength > 0) {
this._paddedKey = new Uint8Array(BLOCK_SIZE);
this._paddedKey.set(config.key);
this._buffer.set(this._paddedKey);
this._bufferLength = BLOCK_SIZE;
}
}
reset() {
this._state.set(this._initialState);
if (this._paddedKey) {
this._buffer.set(this._paddedKey);
this._bufferLength = BLOCK_SIZE;
} else {
this._bufferLength = 0;
}
wipe(this._ctr);
wipe(this._flag);
this._finished = false;
return this;
}
validateConfig(config) {
if (config.key && config.key.length > KEY_LENGTH) {
throw new Error("blake2b: wrong key length");
}
if (config.salt && config.salt.length !== SALT_LENGTH) {
throw new Error("blake2b: wrong salt length");
}
if (config.personalization && config.personalization.length !== PERSONALIZATION_LENGTH) {
throw new Error("blake2b: wrong personalization length");
}
if (config.tree) {
if (config.tree.fanout < 0 || config.tree.fanout > MAX_FANOUT) {
throw new Error("blake2b: wrong tree fanout");
}
if (config.tree.maxDepth < 0 || config.tree.maxDepth > MAX_MAX_DEPTH) {
throw new Error("blake2b: wrong tree depth");
}
if (config.tree.leafSize < 0 || config.tree.leafSize > MAX_LEAF_SIZE) {
throw new Error("blake2b: wrong leaf size");
}
if (config.tree.innerDigestLength < 0 || config.tree.innerDigestLength > DIGEST_LENGTH) {
throw new Error("blake2b: wrong tree inner digest length");
}
}
}
update(data, dataLength = data.length) {
if (this._finished) {
throw new Error("blake2b: can't update because hash was finished.");
}
const left = BLOCK_SIZE - this._bufferLength;
let dataPos = 0;
if (dataLength === 0) {
return this;
}
if (dataLength > left) {
for (let i = 0; i < left; i++) {
this._buffer[this._bufferLength + i] = data[dataPos + i];
}
this._processBlock(BLOCK_SIZE);
dataPos += left;
dataLength -= left;
this._bufferLength = 0;
}
while (dataLength > BLOCK_SIZE) {
for (let i = 0; i < BLOCK_SIZE; i++) {
this._buffer[i] = data[dataPos + i];
}
this._processBlock(BLOCK_SIZE);
dataPos += BLOCK_SIZE;
dataLength -= BLOCK_SIZE;
this._bufferLength = 0;
}
for (let i = 0; i < dataLength; i++) {
this._buffer[this._bufferLength + i] = data[dataPos + i];
}
this._bufferLength += dataLength;
return this;
}
finish(out) {
if (!this._finished) {
for (let i = this._bufferLength; i < BLOCK_SIZE; i++) {
this._buffer[i] = 0;
}
this._flag[0] = 4294967295;
this._flag[1] = 4294967295;
if (this._lastNode) {
this._flag[2] = 4294967295;
this._flag[3] = 4294967295;
}
this._processBlock(this._bufferLength);
this._finished = true;
}
const tmp = this._buffer.subarray(0, 64);
for (let i = 0; i < 16; i++) {
writeUint32LE(this._state[i], tmp, i * 4);
}
out.set(tmp.subarray(0, out.length));
return this;
}
digest() {
const out = new Uint8Array(this.digestLength);
this.finish(out);
return out;
}
clean() {
wipe(this._vtmp);
wipe(this._mtmp);
wipe(this._state);
wipe(this._buffer);
wipe(this._initialState);
if (this._paddedKey) {
wipe(this._paddedKey);
}
this._bufferLength = 0;
wipe(this._ctr);
wipe(this._flag);
this._lastNode = false;
this._finished = false;
}
saveState() {
if (this._finished) {
throw new Error("blake2b: cannot save finished state");
}
return {
state: new Uint32Array(this._state),
buffer: new Uint8Array(this._buffer),
bufferLength: this._bufferLength,
ctr: new Uint32Array(this._ctr),
flag: new Uint32Array(this._flag),
lastNode: this._lastNode,
paddedKey: this._paddedKey ? new Uint8Array(this._paddedKey) : void 0,
initialState: new Uint32Array(this._initialState)
};
}
restoreState(savedState) {
this._state.set(savedState.state);
this._buffer.set(savedState.buffer);
this._bufferLength = savedState.bufferLength;
this._ctr.set(savedState.ctr);
this._flag.set(savedState.flag);
this._lastNode = savedState.lastNode;
if (this._paddedKey) {
wipe(this._paddedKey);
}
this._paddedKey = savedState.paddedKey ? new Uint8Array(savedState.paddedKey) : void 0;
this._initialState.set(savedState.initialState);
return this;
}
cleanSavedState(savedState) {
wipe(savedState.state);
wipe(savedState.buffer);
wipe(savedState.initialState);
if (savedState.paddedKey) {
wipe(savedState.paddedKey);
}
savedState.bufferLength = 0;
wipe(savedState.ctr);
wipe(savedState.flag);
savedState.lastNode = false;
}
_G(v, al, bl, cl, dl, ah, bh, ch, dh, ml0, mh0, ml1, mh1) {
let vla = v[al], vha = v[ah], vlb = v[bl], vhb = v[bh], vlc = v[cl], vhc = v[ch], vld = v[dl], vhd = v[dh];
let w = vla & 65535, x = vla >>> 16, y = vha & 65535, z = vha >>> 16;
w += vlb & 65535;
x += vlb >>> 16;
y += vhb & 65535;
z += vhb >>> 16;
x += w >>> 16;
y += x >>> 16;
z += y >>> 16;
vha = y & 65535 | z << 16;
vla = w & 65535 | x << 16;
w = vla & 65535;
x = vla >>> 16;
y = vha & 65535;
z = vha >>> 16;
w += ml0 & 65535;
x += ml0 >>> 16;
y += mh0 & 65535;
z += mh0 >>> 16;
x += w >>> 16;
y += x >>> 16;
z += y >>> 16;
vha = y & 65535 | z << 16;
vla = w & 65535 | x << 16;
vld ^= vla;
vhd ^= vha;
w = vhd;
vhd = vld;
vld = w;
w = vlc & 65535;
x = vlc >>> 16;
y = vhc & 65535;
z = vhc >>> 16;
w += vld & 65535;
x += vld >>> 16;
y += vhd & 65535;
z += vhd >>> 16;
x += w >>> 16;
y += x >>> 16;
z += y >>> 16;
vhc = y & 65535 | z << 16;
vlc = w & 65535 | x << 16;
vlb ^= vlc;
vhb ^= vhc;
w = vlb << 8 | vhb >>> 24;
vlb = vhb << 8 | vlb >>> 24;
vhb = w;
w = vla & 65535;
x = vla >>> 16;
y = vha & 65535;
z = vha >>> 16;
w += vlb & 65535;
x += vlb >>> 16;
y += vhb & 65535;
z += vhb >>> 16;
x += w >>> 16;
y += x >>> 16;
z += y >>> 16;
vha = y & 65535 | z << 16;
vla = w & 65535 | x << 16;
w = vla & 65535;
x = vla >>> 16;
y = vha & 65535;
z = vha >>> 16;
w += ml1 & 65535;
x += ml1 >>> 16;
y += mh1 & 65535;
z += mh1 >>> 16;
x += w >>> 16;
y += x >>> 16;
z += y >>> 16;
vha = y & 65535 | z << 16;
vla = w & 65535 | x << 16;
vld ^= vla;
vhd ^= vha;
w = vld << 16 | vhd >>> 16;
vld = vhd << 16 | vld >>> 16;
vhd = w;
w = vlc & 65535;
x = vlc >>> 16;
y = vhc & 65535;
z = vhc >>> 16;
w += vld & 65535;
x += vld >>> 16;
y += vhd & 65535;
z += vhd >>> 16;
x += w >>> 16;
y += x >>> 16;
z += y >>> 16;
vhc = y & 65535 | z << 16;
vlc = w & 65535 | x << 16;
vlb ^= vlc;
vhb ^= vhc;
w = vhb << 1 | vlb >>> 31;
vlb = vlb << 1 | vhb >>> 31;
vhb = w;
v[al] = vla;
v[ah] = vha;
v[bl] = vlb;
v[bh] = vhb;
v[cl] = vlc;
v[ch] = vhc;
v[dl] = vld;
v[dh] = vhd;
}
_incrementCounter(n) {
for (let i = 0; i < 3; i++) {
let a = this._ctr[i] + n;
this._ctr[i] = a >>> 0;
if (this._ctr[i] === a) {
return;
}
n = 1;
}
}
_processBlock(length) {
this._incrementCounter(length);
let v = this._vtmp;
v.set(this._state);
v.set(IV, 16);
v[12 * 2 + 0] ^= this._ctr[0];
v[12 * 2 + 1] ^= this._ctr[1];
v[13 * 2 + 0] ^= this._ctr[2];
v[13 * 2 + 1] ^= this._ctr[3];
v[14 * 2 + 0] ^= this._flag[0];
v[14 * 2 + 1] ^= this._flag[1];
v[15 * 2 + 0] ^= this._flag[2];
v[15 * 2 + 1] ^= this._flag[3];
let m = this._mtmp;
for (let i = 0; i < 32; i++) {
m[i] = readUint32LE(this._buffer, i * 4);
}
for (let r = 0; r < 12; r++) {
this._G(v, 0, 8, 16, 24, 1, 9, 17, 25, m[SIGMA[r][0]], m[SIGMA[r][0] + 1], m[SIGMA[r][1]], m[SIGMA[r][1] + 1]);
this._G(v, 2, 10, 18, 26, 3, 11, 19, 27, m[SIGMA[r][2]], m[SIGMA[r][2] + 1], m[SIGMA[r][3]], m[SIGMA[r][3] + 1]);
this._G(v, 4, 12, 20, 28, 5, 13, 21, 29, m[SIGMA[r][4]], m[SIGMA[r][4] + 1], m[SIGMA[r][5]], m[SIGMA[r][5] + 1]);
this._G(v, 6, 14, 22, 30, 7, 15, 23, 31, m[SIGMA[r][6]], m[SIGMA[r][6] + 1], m[SIGMA[r][7]], m[SIGMA[r][7] + 1]);
this._G(v, 0, 10, 20, 30, 1, 11, 21, 31, m[SIGMA[r][8]], m[SIGMA[r][8] + 1], m[SIGMA[r][9]], m[SIGMA[r][9] + 1]);
this._G(v, 2, 12, 22, 24, 3, 13, 23, 25, m[SIGMA[r][10]], m[SIGMA[r][10] + 1], m[SIGMA[r][11]], m[SIGMA[r][11] + 1]);
this._G(v, 4, 14, 16, 26, 5, 15, 17, 27, m[SIGMA[r][12]], m[SIGMA[r][12] + 1], m[SIGMA[r][13]], m[SIGMA[r][13] + 1]);
this._G(v, 6, 8, 18, 28, 7, 9, 19, 29, m[SIGMA[r][14]], m[SIGMA[r][14] + 1], m[SIGMA[r][15]], m[SIGMA[r][15] + 1]);
}
for (let i = 0; i < 16; i++) {
this._state[i] ^= v[i] ^ v[i + 16];
}
}
};
// node_modules/@stablelib/chacha/lib/chacha.js
var ROUNDS = 20;
function core(out, input, key) {
let j0 = 1634760805;
let j1 = 857760878;
let j2 = 2036477234;
let j3 = 1797285236;
let j4 = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
let j5 = key[7] << 24 | key[6] << 16 | key[5] << 8 | key[4];
let j6 = key[11] << 24 | key[10] << 16 | key[9] << 8 | key[8];
let j7 = key[15] << 24 | key[14] << 16 | key[13] << 8 | key[12];
let j8 = key[19] << 24 | key[18] << 16 | key[17] << 8 | key[16];
let j9 = key[23] << 24 | key[22] << 16 | key[21] << 8 | key[20];
let j10 = key[27] << 24 | key[26] << 16 | key[25] << 8 | key[24];
let j11 = key[31] << 24 | key[30] << 16 | key[29] << 8 | key[28];
let j12 = input[3] << 24 | input[2] << 16 | input[1] << 8 | input[0];
let j13 = input[7] << 24 | input[6] << 16 | input[5] << 8 | input[4];
let j14 = input[11] << 24 | input[10] << 16 | input[9] << 8 | input[8];
let j15 = input[15] << 24 | input[14] << 16 | input[13] << 8 | input[12];
let x0 = j0;
let x1 = j1;
let x2 = j2;
let x3 = j3;
let x4 = j4;
let x5 = j5;
let x6 = j6;
let x7 = j7;
let x8 = j8;
let x9 = j9;
let x10 = j10;
let x11 = j11;
let x12 = j12;
let x13 = j13;
let x14 = j14;
let x15 = j15;
for (let i = 0; i < ROUNDS; i += 2) {
x0 = x0 + x4 | 0;
x12 ^= x0;
x12 = x12 >>> 32 - 16 | x12 << 16;
x8 = x8 + x12 | 0;
x4 ^= x8;
x4 = x4 >>> 32 - 12 | x4 << 12;
x1 = x1 + x5 | 0;
x13 ^= x1;
x13 = x13 >>> 32 - 16 | x13 << 16;
x9 = x9 + x13 | 0;
x5 ^= x9;
x5 = x5 >>> 32 - 12 | x5 << 12;
x2 = x2 + x6 | 0;
x14 ^= x2;
x14 = x14 >>> 32 - 16 | x14 << 16;
x10 = x10 + x14 | 0;
x6 ^= x10;
x6 = x6 >>> 32 - 12 | x6 << 12;
x3 = x3 + x7 | 0;
x15 ^= x3;
x15 = x15 >>> 32 - 16 | x15 << 16;
x11 = x11 + x15 | 0;
x7 ^= x11;
x7 = x7 >>> 32 - 12 | x7 << 12;
x2 = x2 + x6 | 0;
x14 ^= x2;
x14 = x14 >>> 32 - 8 | x14 << 8;
x10 = x10 + x14 | 0;
x6 ^= x10;
x6 = x6 >>> 32 - 7 | x6 << 7;
x3 = x3 + x7 | 0;
x15 ^= x3;
x15 = x15 >>> 32 - 8 | x15 << 8;
x11 = x11 + x15 | 0;
x7 ^= x11;
x7 = x7 >>> 32 - 7 | x7 << 7;
x1 = x1 + x5 | 0;
x13 ^= x1;
x13 = x13 >>> 32 - 8 | x13 << 8;
x9 = x9 + x13 | 0;
x5 ^= x9;
x5 = x5 >>> 32 - 7 | x5 << 7;
x0 = x0 + x4 | 0;
x12 ^= x0;
x12 = x12 >>> 32 - 8 | x12 << 8;
x8 = x8 + x12 | 0;
x4 ^= x8;
x4 = x4 >>> 32 - 7 | x4 << 7;
x0 = x0 + x5 | 0;
x15 ^= x0;
x15 = x15 >>> 32 - 16 | x15 << 16;
x10 = x10 + x15 | 0;
x5 ^= x10;
x5 = x5 >>> 32 - 12 | x5 << 12;
x1 = x1 + x6 | 0;
x12 ^= x1;
x12 = x12 >>> 32 - 16 | x12 << 16;
x11 = x11 + x12 | 0;
x6 ^= x11;
x6 = x6 >>> 32 - 12 | x6 << 12;
x2 = x2 + x7 | 0;
x13 ^= x2;
x13 = x13 >>> 32 - 16 | x13 << 16;
x8 = x8 + x13 | 0;
x7 ^= x8;
x7 = x7 >>> 32 - 12 | x7 << 12;
x3 = x3 + x4 | 0;
x14 ^= x3;
x14 = x14 >>> 32 - 16 | x14 << 16;
x9 = x9 + x14 | 0;
x4 ^= x9;
x4 = x4 >>> 32 - 12 | x4 << 12;
x2 = x2 + x7 | 0;
x13 ^= x2;
x13 = x13 >>> 32 - 8 | x13 << 8;
x8 = x8 + x13 | 0;
x7 ^= x8;
x7 = x7 >>> 32 - 7 | x7 << 7;
x3 = x3 + x4 | 0;
x14 ^= x3;
x14 = x14 >>> 32 - 8 | x14 << 8;
x9 = x9 + x14 | 0;
x4 ^= x9;
x4 = x4 >>> 32 - 7 | x4 << 7;
x1 = x1 + x6 | 0;
x12 ^= x1;
x12 = x12 >>> 32 - 8 | x12 << 8;
x11 = x11 + x12 | 0;
x6 ^= x11;
x6 = x6 >>> 32 - 7 | x6 << 7;
x0 = x0 + x5 | 0;
x15 ^= x0;
x15 = x15 >>> 32 - 8 | x15 << 8;
x10 = x10 + x15 | 0;
x5 ^= x10;
x5 = x5 >>> 32 - 7 | x5 << 7;
}
writeUint32LE(x0 + j0 | 0, out, 0);
writeUint32LE(x1 + j1 | 0, out, 4);
writeUint32LE(x2 + j2 | 0, out, 8);
writeUint32LE(x3 + j3 | 0, out, 12);
writeUint32LE(x4 + j4 | 0, out, 16);
writeUint32LE(x5 + j5 | 0, out, 20);
writeUint32LE(x6 + j6 | 0, out, 24);
writeUint32LE(x7 + j7 | 0, out, 28);
writeUint32LE(x8 + j8 | 0, out, 32);
writeUint32LE(x9 + j9 | 0, out, 36);
writeUint32LE(x10 + j10 | 0, out, 40);
writeUint32LE(x11 + j11 | 0, out, 44);
writeUint32LE(x12 + j12 | 0, out, 48);
writeUint32LE(x13 + j13 | 0, out, 52);
writeUint32LE(x14 + j14 | 0, out, 56);
writeUint32LE(x15 + j15 | 0, out, 60);
}
function streamXOR(key, nonce, src, dst, nonceInplaceCounterLength = 0) {
if (key.length !== 32) {
throw new Error("ChaCha: key size must be 32 bytes");
}
if (dst.length < src.length) {
throw new Error("ChaCha: destination is shorter than source");
}
let nc;
let counterLength;
if (nonceInplaceCounterLength === 0) {
if (nonce.length !== 8 && nonce.length !== 12) {
throw new Error("ChaCha nonce must be 8 or 12 bytes");
}
nc = new Uint8Array(16);
counterLength = nc.length - nonce.length;
nc.set(nonce, counterLength);
} else {
if (nonce.length !== 16) {
throw new Error("ChaCha nonce with counter must be 16 bytes");
}
nc = nonce;
counterLength = nonceInplaceCounterLength;
}
const block = new Uint8Array(64);
for (let i = 0; i < src.length; i += 64) {
core(block, nc, key);
for (let j = i; j < i + 64 && j < src.length; j++) {
dst[j] = src[j] ^ block[j - i];
}
incrementCounter(nc, 0, counterLength);
}
wipe(block);
if (nonceInplaceCounterLength === 0) {
wipe(nc);
}
return dst;
}
function stream(key, nonce, dst, nonceInplaceCounterLength = 0) {
wipe(dst);
return streamXOR(key, nonce, dst, dst, nonceInplaceCounterLength);
}
function incrementCounter(counter, pos, len) {
let carry = 1;
while (len--) {
carry = carry + (counter[pos] & 255) | 0;
counter[pos] = carry & 255;
carry >>>= 8;
pos++;
}
if (carry > 0) {
throw new Error("ChaCha: counter overflow");
}
}
// node_modules/@stablelib/xchacha20/lib/xchacha20.js
var ROUNDS2 = 20;
function hchacha(key, src, dst) {
let j0 = 1634760805;
let j1 = 857760878;
let j2 = 2036477234;
let j3 = 1797285236;
let j4 = key[3] << 24 | key[2] << 16 | key[1] << 8 | key[0];
let j5 = key[7] << 24 | key[6] << 16 | key[5] << 8 | key[4];
let j6 = key[11] << 24 | key[10] << 16 | key[9] << 8 | key[8];
let j7 = key[15] << 24 | key[14] << 16 | key[13] << 8 | key[12];
let j8 = key[19] << 24 | key[18] << 16 | key[17] << 8 | key[16];
let j9 = key[23] << 24 | key[22] << 16 | key[21] << 8 | key[20];
let j10 = key[27] << 24 | key[26] << 16 | key[25] << 8 | key[24];
let j11 = key[31] << 24 | key[30] << 16 | key[29] << 8 | key[28];
let j12 = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0];
let j13 = src[7] << 24 | src[6] << 16 | src[5] << 8 | src[4];
let j14 = src[11] << 24 | src[10] << 16 | src[9] << 8 | src[8];
let j15 = src[15] << 24 | src[14] << 16 | src[13] << 8 | src[12];
let x0 = j0;
let x1 = j1;
let x2 = j2;
let x3 = j3;
let x4 = j4;
let x5 = j5;
let x6 = j6;
let x7 = j7;
let x8 = j8;
let x9 = j9;
let x10 = j10;
let x11 = j11;
let x12 = j12;
let x13 = j13;
let x14 = j14;
let x15 = j15;
for (let i = 0; i < ROUNDS2; i += 2) {
x0 = x0 + x4 | 0;
x12 ^= x0;
x12 = x12 >>> 32 - 16 | x12 << 16;
x8 = x8 + x12 | 0;
x4 ^= x8;
x4 = x4 >>> 32 - 12 | x4 << 12;
x1 = x1 + x5 | 0;
x13 ^= x1;
x13 = x13 >>> 32 - 16 | x13 << 16;
x9 = x9 + x13 | 0;
x5 ^= x9;
x5 = x5 >>> 32 - 12 | x5 << 12;
x2 = x2 + x6 | 0;
x14 ^= x2;
x14 = x14 >>> 32 - 16 | x14 << 16;
x10 = x10 + x14 | 0;
x6 ^= x10;
x6 = x6 >>> 32 - 12 | x6 << 12;
x3 = x3 + x7 | 0;
x15 ^= x3;
x15 = x15 >>> 32 - 16 | x15 << 16;
x11 = x11 + x15 | 0;
x7 ^= x11;
x7 = x7 >>> 32 - 12 | x7 << 12;
x2 = x2 + x6 | 0;
x14 ^= x2;
x14 = x14 >>> 32 - 8 | x14 << 8;
x10 = x10 + x14 | 0;
x6 ^= x10;
x6 = x6 >>> 32 - 7 | x6 << 7;
x3 = x3 + x7 | 0;
x15 ^= x3;
x15 = x15 >>> 32 - 8 | x15 << 8;
x11 = x11 + x15 | 0;
x7 ^= x11;
x7 = x7 >>> 32 - 7 | x7 << 7;
x1 = x1 + x5 | 0;
x13 ^= x1;
x13 = x13 >>> 32 - 8 | x13 << 8;
x9 = x9 + x13 | 0;
x5 ^= x9;
x5 = x5 >>> 32 - 7 | x5 << 7;
x0 = x0 + x4 | 0;
x12 ^= x0;
x12 = x12 >>> 32 - 8 | x12 << 8;
x8 = x8 + x12 | 0;
x4 ^= x8;
x4 = x4 >>> 32 - 7 | x4 << 7;
x0 = x0 + x5 | 0;
x15 ^= x0;
x15 = x15 >>> 32 - 16 | x15 << 16;
x10 = x10 + x15 | 0;
x5 ^= x10;
x5 = x5 >>> 32 - 12 | x5 << 12;
x1 = x1 + x6 | 0;
x12 ^= x1;
x12 = x12 >>> 32 - 16 | x12 << 16;
x11 = x11 + x12 | 0;
x6 ^= x11;
x6 = x6 >>> 32 - 12 | x6 << 12;
x2 = x2 + x7 | 0;
x13 ^= x2;
x13 = x13 >>> 32 - 16 | x13 << 16;
x8 = x8 + x13 | 0;
x7 ^= x8;
x7 = x7 >>> 32 - 12 | x7 << 12;
x3 = x3 + x4 | 0;
x14 ^= x3;
x14 = x14 >>> 32 - 16 | x14 << 16;
x9 = x9 + x14 | 0;
x4 ^= x9;
x4 = x4 >>> 32 - 12 | x4 << 12;
x2 = x2 + x7 | 0;
x13 ^= x2;
x13 = x13 >>> 32 - 8 | x13 << 8;
x8 = x8 + x13 | 0;
x7 ^= x8;
x7 = x7 >>> 32 - 7 | x7 << 7;
x3 = x3 + x4 | 0;
x14 ^= x3;
x14 = x14 >>> 32 - 8 | x14 << 8;
x9 = x9 + x14 | 0;
x4 ^= x9;
x4 = x4 >>> 32 - 7 | x4 << 7;
x1 = x1 + x6 | 0;
x12 ^= x1;
x12 = x12 >>> 32 - 8 | x12 << 8;
x11 = x11 + x12 | 0;
x6 ^= x11;
x6 = x6 >>> 32 - 7 | x6 << 7;
x0 = x0 + x5 | 0;
x15 ^= x0;
x15 = x15 >>> 32 - 8 | x15 << 8;
x10 = x10 + x15 | 0;
x5 ^= x10;
x5 = x5 >>> 32 - 7 | x5 << 7;
}
writeUint32LE(x0, dst, 0);
writeUint32LE(x1, dst, 4);
writeUint32LE(x2, dst, 8);
writeUint32LE(x3, dst, 12);
writeUint32LE(x12, dst, 16);
writeUint32LE(x13, dst, 20);
writeUint32LE(x14, dst, 24);
writeUint32LE(x15, dst, 28);
return dst;
}
// node_modules/@stablelib/constant-time/lib/constant-time.js
function compare(a, b) {
if (a.length !== b.length) {
return 0;
}
let result = 0;
for (let i = 0; i < a.length; i++) {
result |= a[i] ^ b[i];
}
return 1 & result - 1 >>> 8;
}
function equal(a, b) {
if (a.length === 0 || b.length === 0) {
return false;
}
return compare(a, b) !== 0;
}
// node_modules/@stablelib/poly1305/lib/poly1305.js
var DIGEST_LENGTH2 = 16;
var Poly1305 = class {
digestLength = DIGEST_LENGTH2;
_buffer = new Uint8Array(16);
_r = new Uint16Array(10);
_h = new Uint16Array(10);
_pad = new Uint16Array(8);
_leftover = 0;
_fin = 0;
_finished = false;
constructor(key) {
let t0 = key[0] | key[1] << 8;
this._r[0] = t0 & 8191;
let t1 = key[2] | key[3] << 8;
this._r[1] = (t0 >>> 13 | t1 << 3) & 8191;
let t2 = key[4] | key[5] << 8;
this._r[2] = (t1 >>> 10 | t2 << 6) & 7939;
let t3 = key[6] | key[7] << 8;
this._r[3] = (t2 >>> 7 | t3 << 9) & 8191;
let t4 = key[8] | key[9] << 8;
this._r[4] = (t3 >>> 4 | t4 << 12) & 255;
this._r[5] = t4 >>> 1 & 8190;
let t5 = key[10] | key[11] << 8;
this._r[6] = (t4 >>> 14 | t5 << 2) & 8191;
let t6 = key[12] | key[13] << 8;
this._r[7] = (t5 >>> 11 | t6 << 5) & 8065;
let t7 = key[14] | key[15] << 8;
this._r[8] = (t6 >>> 8 | t7 << 8) & 8191;
this._r[9] = t7 >>> 5 & 127;
this._pad[0] = key[16] | key[17] << 8;
this._pad[1] = key[18] | key[19] << 8;
this._pad[2] = key[20] | key[21] << 8;
this._pad[3] = key[22] | key[23] << 8;
this._pad[4] = key[24] | key[25] << 8;
this._pad[5] = key[26] | key[27] << 8;
this._pad[6] = key[28] | key[29] << 8;
this._pad[7] = key[30] | key[31] << 8;
}
_blocks(m, mpos, bytes) {
let hibit = this._fin ? 0 : 1 << 11;
let h0 = this._h[0], h1 = this._h[1], h2 = this._h[2], h3 = this._h[3], h4 = this._h[4], h5 = this._h[5], h6 = this._h[6], h7 = this._h[7], h8 = this._h[8], h9 = this._h[9];
let r0 = this._r[0], r1 = this._r[1], r2 = this._r[2], r3 = this._r[3], r4 = this._r[4], r5 = this._r[5], r6 = this._r[6], r7 = this._r[7], r8 = this._r[8], r9 = this._r[9];
while (bytes >= 16) {
let t0 = m[mpos + 0] | m[mpos + 1] << 8;
h0 += t0 & 8191;
let t1 = m[mpos + 2] | m[mpos + 3] << 8;
h1 += (t0 >>> 13 | t1 << 3) & 8191;
let t2 = m[mpos + 4] | m[mpos + 5] << 8;
h2 += (t1 >>> 10 | t2 << 6) & 8191;
let t3 = m[mpos + 6] | m[mpos + 7] << 8;
h3 += (t2 >>> 7 | t3 << 9) & 8191;
let t4 = m[mpos + 8] | m[mpos + 9] << 8;
h4 += (t3 >>> 4 | t4 << 12) & 8191;
h5 += t4 >>> 1 & 8191;
let t5 = m[mpos + 10] | m[mpos + 11] << 8;
h6 += (t4 >>> 14 | t5 << 2) & 8191;
let t6 = m[mpos + 12] | m[mpos + 13] << 8;
h7 += (t5 >>> 11 | t6 << 5) & 8191;
let t7 = m[mpos + 14] | m[mpos + 15] << 8;
h8 += (t6 >>> 8 | t7 << 8) & 8191;
h9 += t7 >>> 5 | hibit;
let c = 0;
let d0 = c;
d0 += h0 * r0;
d0 += h1 * (5 * r9);
d0 += h2 * (5 * r8);
d0 += h3 * (5 * r7);
d0 += h4 * (5 * r6);
c = d0 >>> 13;
d0 &= 8191;
d0 += h5 * (5 * r5);
d0 += h6 * (5 * r4);
d0 += h7 * (5 * r3);
d0 += h8 * (5 * r2);
d0 += h9 * (5 * r1);
c += d0 >>> 13;
d0 &= 8191;
let d1 = c;
d1 += h0 * r1;
d1 += h1 * r0;
d1 += h2 * (5 * r9);
d1 += h3 * (5 * r8);
d1 += h4 * (5 * r7);
c = d1 >>> 13;
d1 &= 8191;
d1 += h5 * (5 * r6);
d1 += h6 * (5 * r5);
d1 += h7 * (5 * r4);
d1 += h8 * (5 * r3);
d1 += h9 * (5 * r2);
c += d1 >>> 13;
d1 &= 8191;
let d2 = c;
d2 += h0 * r2;
d2 += h1 * r1;
d2 += h2 * r0;
d2 += h3 * (5 * r9);
d2 += h4 * (5 * r8);
c = d2 >>> 13;
d2 &= 8191;
d2 += h5 * (5 * r7);
d2 += h6 * (5 * r6);
d2 += h7 * (5 * r5);
d2 += h8 * (5 * r4);
d2 += h9 * (5 * r3);
c += d2 >>> 13;
d2 &= 8191;
let d3 = c;
d3 += h0 * r3;
d3 += h1 * r2;
d3 += h2 * r1;
d3 += h3 * r0;
d3 += h4 * (5 * r9);
c = d3 >>> 13;
d3 &= 8191;
d3 += h5 * (5 * r8);
d3 += h6 * (5 * r7);
d3 += h7 * (5 * r6);
d3 += h8 * (5 * r5);
d3 += h9 * (5 * r4);
c += d3 >>> 13;
d3 &= 8191;
let d4 = c;
d4 += h0 * r4;
d4 += h1 * r3;
d4 += h2 * r2;
d4 += h3 * r1;
d4 += h4 * r0;
c = d4 >>> 13;
d4 &= 8191;
d4 += h5 * (5 * r9);
d4 += h6 * (5 * r8);
d4 += h7 * (5 * r7);
d4 += h8 * (5 * r6);
d4 += h9 * (5 * r5);
c += d4 >>> 13;
d4 &= 8191;
let d5 = c;
d5 += h0 * r5;
d5 += h1 * r4;
d5 += h2 * r3;
d5 += h3 * r2;
d5 += h4 * r1;
c = d5 >>> 13;
d5 &= 8191;
d5 += h5 * r0;
d5 += h6 * (5 * r9);
d5 += h7 * (5 * r8);
d5 += h8 * (5 * r7);
d5 += h9 * (5 * r6);
c += d5 >>> 13;
d5 &= 8191;
let d6 = c;
d6 += h0 * r6;
d6 += h1 * r5;
d6 += h2 * r4;
d6 += h3 * r3;
d6 += h4 * r2;
c = d6 >>> 13;
d6 &= 8191;
d6 += h5 * r1;
d6 += h6 * r0;
d6 += h7 * (5 * r9);
d6 += h8 * (5 * r8);
d6 += h9 * (5 * r7);
c += d6 >>> 13;
d6 &= 8191;
let d7 = c;
d7 += h0 * r7;
d7 += h1 * r6;
d7 += h2 * r5;
d7 += h3 * r4;
d7 += h4 * r3;
c = d7 >>> 13;
d7 &= 8191;
d7 += h5 * r2;
d7 += h6 * r1;
d7 += h7 * r0;
d7 += h8 * (5 * r9);
d7 += h9 * (5 * r8);
c += d7 >>> 13;
d7 &= 8191;
let d8 = c;
d8 += h0 * r8;
d8 += h1 * r7;
d8 += h2 * r6;
d8 += h3 * r5;
d8 += h4 * r4;
c = d8 >>> 13;
d8 &= 8191;
d8 += h5 * r3;
d8 += h6 * r2;
d8 += h7 * r1;
d8 += h8 * r0;
d8 += h9 * (5 * r9);
c += d8 >>> 13;
d8 &= 8191;
let d9 = c;
d9 += h0 * r9;
d9 += h1 * r8;
d9 += h2 * r7;
d9 += h3 * r6;
d9 += h4 * r5;
c = d9 >>> 13;
d9 &= 8191;
d9 += h5 * r4;
d9 += h6 * r3;
d9 += h7 * r2;
d9 += h8 * r1;
d9 += h9 * r0;
c += d9 >>> 13;
d9 &= 8191;
c = (c << 2) + c | 0;
c = c + d0 | 0;
d0 = c & 8191;
c = c >>> 13;
d1 += c;
h0 = d0;
h1 = d1;
h2 = d2;
h3 = d3;
h4 = d4;
h5 = d5;
h6 = d6;
h7 = d7;
h8 = d8;
h9 = d9;
mpos += 16;
bytes -= 16;
}
this._h[0] = h0;
this._h[1] = h1;
this._h[2] = h2;
this._h[3] = h3;
this._h[4] = h4;
this._h[5] = h5;
this._h[6] = h6;
this._h[7] = h7;
this._h[8] = h8;
this._h[9] = h9;
}
finish(mac, macpos = 0) {
const g = new Uint16Array(10);
let c;
let mask;
let f;
let i;
if (this._leftover) {
i = this._leftover;
this._buffer[i++] = 1;
for (; i < 16; i++) {
this._buffer[i] = 0;
}
this._fin = 1;
this._blocks(this._buffer, 0, 16);
}
c = this._h[1] >>> 13;
this._h[1] &= 8191;
for (i = 2; i < 10; i++) {
this._h[i] += c;
c = this._h[i] >>> 13;
this._h[i] &= 8191;
}
this._h[0] += c * 5;
c = this._h[0] >>> 13;
this._h[0] &= 8191;
this._h[1] += c;
c = this._h[1] >>> 13;
this._h[1] &= 8191;
this._h[2] += c;
g[0] = this._h[0] + 5;
c = g[0] >>> 13;
g[0] &= 8191;
for (i = 1; i < 10; i++) {
g[i] = this._h[i] + c;
c = g[i] >>> 13;
g[i] &= 8191;
}
g[9] -= 1 << 13;
mask = (c ^ 1) - 1;
for (i = 0; i < 10; i++) {
g[i] &= mask;
}
mask = ~mask;
for (i = 0; i < 10; i++) {
this._h[i] = this._h[i] & mask | g[i];
}
this._h[0] = (this._h[0] | this._h[1] << 13) & 65535;
this._h[1] = (this._h[1] >>> 3 | this._h[2] << 10) & 65535;
this._h[2] = (this._h[2] >>> 6 | this._h[3] << 7) & 65535;
this._h[3] = (this._h[3] >>> 9 | this._h[4] << 4) & 65535;
this._h[4] = (this._h[4] >>> 12 | this._h[5] << 1 | this._h[6] << 14) & 65535;
this._h[5] = (this._h[6] >>> 2 | this._h[7] << 11) & 65535;
this._h[6] = (this._h[7] >>> 5 | this._h[8] << 8) & 65535;
this._h[7] = (this._h[8] >>> 8 | this._h[9] << 5) & 65535;
f = this._h[0] + this._pad[0];
this._h[0] = f & 65535;
for (i = 1; i < 8; i++) {
f = (this._h[i] + this._pad[i] | 0) + (f >>> 16) | 0;
this._h[i] = f & 65535;
}
mac[macpos + 0] = this._h[0] >>> 0;
mac[macpos + 1] = this._h[0] >>> 8;
mac[macpos + 2] = this._h[1] >>> 0;
mac[macpos + 3] = this._h[1] >>> 8;
mac[macpos + 4] = this._h[2] >>> 0;
mac[macpos + 5] = this._h[2] >>> 8;
mac[macpos + 6] = this._h[3] >>> 0;
mac[macpos + 7] = this._h[3] >>> 8;
mac[macpos + 8] = this._h[4] >>> 0;
mac[macpos + 9] = this._h[4] >>> 8;
mac[macpos + 10] = this._h[5] >>> 0;
mac[macpos + 11] = this._h[5] >>> 8;
mac[macpos + 12] = this._h[6] >>> 0;
mac[macpos + 13] = this._h[6] >>> 8;
mac[macpos + 14] = this._h[7] >>> 0;
mac[macpos + 15] = this._h[7] >>> 8;
this._finished = true;
return this;
}
update(m) {
let mpos = 0;
let bytes = m.length;
let want;
if (this._leftover) {
want = 16 - this._leftover;
if (want > bytes) {
want = bytes;
}
for (let i = 0; i < want; i++) {
this._buffer[this._leftover + i] = m[mpos + i];
}
bytes -= want;
mpos += want;
this._leftover += want;
if (this._leftover < 16) {
return this;
}
this._blocks(this._buffer, 0, 16);
this._leftover = 0;
}
if (bytes >= 16) {
want = bytes - bytes % 16;
this._blocks(m, mpos, want);
mpos += want;
bytes -= want;
}
if (bytes) {
for (let i = 0; i < bytes; i++) {
this._buffer[this._leftover + i] = m[mpos + i];
}
this._leftover += bytes;
}
return this;
}
digest() {
if (this._finished) {
throw new Error("Poly1305 was finished");
}
let mac = new Uint8Array(16);
this.finish(mac);
return mac;
}
clean() {
wipe(this._buffer);
wipe(this._r);
wipe(this._h);
wipe(this._pad);
this._leftover = 0;
this._fin = 0;
this._finished = true;
return this;
}
};
// node_modules/@stablelib/chacha20poly1305/lib/chacha20poly1305.js
var KEY_LENGTH2 = 32;
var NONCE_LENGTH = 12;
var TAG_LENGTH = 16;
var ZEROS = new Uint8Array(16);
var ChaCha20Poly1305 = class {
nonceLength = NONCE_LENGTH;
tagLength = TAG_LENGTH;
_key;
/**
* Creates a new instance with the given 32-byte key.
*/
constructor(key) {
if (key.length !== KEY_LENGTH2) {
throw new Error("ChaCha20Poly1305 needs 32-byte key");
}
this._key = new Uint8Array(key);
}
/**
* Encrypts and authenticates plaintext, authenticates associated data,
* and returns sealed ciphertext, which includes authentication tag.
*
* RFC7539 specifies 12 bytes for nonce. It may be this 12-byte nonce
* ("IV"), or full 16-byte counter (called "32-bit fixed-common part")
* and nonce.
*
* If dst is given (it must be the size of plaintext + the size of tag
* length) the result will be put into it. Dst and plaintext must not
* overlap.
*/
seal(nonce, plaintext, associatedData, dst) {
if (nonce.length > 16) {
throw new Error("ChaCha20Poly1305: incorrect nonce length");
}
const counter = new Uint8Array(16);
counter.set(nonce, counter.length - nonce.length);
const authKey = new Uint8Array(32);
stream(this._key, counter, authKey, 4);
const resultLength = plaintext.length + this.tagLength;
let result;
if (dst) {
if (dst.length !== resultLength) {
throw new Error("ChaCha20Poly1305: incorrect destination length");
}
result = dst;
} else {
result = new Uint8Array(resultLength);
}
streamXOR(this._key, counter, plaintext, result, 4);
this._authenticate(result.subarray(result.length - this.tagLength, result.length), authKey, result.subarray(0, result.length - this.tagLength), associatedData);
wipe(counter);
return result;
}
/**
* Authenticates sealed ciphertext (which includes authentication tag) and
* associated data, decrypts ciphertext and returns decrypted plaintext.
*
* RFC7539 specifies 12 bytes for nonce. It may be this 12-byte nonce
* ("IV"), or full 16-byte counter (called "32-bit fixed-common part")
* and nonce.
*
* If authentication fails, it returns null.
*
* If dst is given (it must be of ciphertext length minus tag length),
* the result will be put into it. Dst and plaintext must not overlap.
*/
open(nonce, sealed, associatedData, dst) {
if (nonce.length > 16) {
throw new Error("ChaCha20Poly1305: incorrect nonce length");
}
if (sealed.length < this.tagLength) {
return null;
}
const counter = new Uint8Array(16);
counter.set(nonce, counter.length - nonce.length);
const authKey = new Uint8Array(32);
stream(this._key, counter, authKey, 4);
const calculatedTag = new Uint8Array(this.tagLength);
this._authenticate(calculatedTag, authKey, sealed.subarray(0, sealed.length - this.tagLength), associatedData);
if (!equal(calculatedTag, sealed.subarray(sealed.length - this.tagLength, sealed.length))) {
return null;
}
const resultLength = sealed.length - this.tagLength;
let result;
if (dst) {
if (dst.length !== resultLength) {
throw new Error("ChaCha20Poly1305: incorrect destination length");
}
result = dst;
} else {
result = new Uint8Array(resultLength);
}
streamXOR(this._key, counter, sealed.subarray(0, sealed.length - this.tagLength), result, 4);
wipe(counter);
return result;
}
clean() {
wipe(this._key);
return this;
}
_authenticate(tagOut, authKey, ciphertext, associatedData) {
const h = new Poly1305(authKey);
if (associatedData) {
h.update(associatedData);
if (associatedData.length % 16 > 0) {
h.update(ZEROS.subarray(associatedData.length % 16));
}
}
h.update(ciphertext);
if (ciphertext.length % 16 > 0) {
h.update(ZEROS.subarray(ciphertext.length % 16));
}
const length = new Uint8Array(8);
if (associatedData) {
writeUint64LE(associatedData.length, length);
}
h.update(length);
writeUint64LE(ciphertext.length, length);
h.update(length);
const tag = h.digest();
for (let i = 0; i < tag.length; i++) {
tagOut[i] = tag[i];
}
h.clean();
wipe(tag);
wipe(length);
}
};
// node_modules/@stablelib/xchacha20poly1305/lib/xchacha20poly1305.js
var KEY_LENGTH3 = 32;
var NONCE_LENGTH2 = 24;
var TAG_LENGTH2 = 16;
var XChaCha20Poly1305 = class {
nonceLength = NONCE_LENGTH2;
tagLength = TAG_LENGTH2;
_key;
/**
* Creates a new instance with the given 32-byte key.
*/
constructor(key) {
if (key.length !== KEY_LENGTH3) {
throw new Error("ChaCha20Poly1305 needs 32-byte key");
}
this._key = new Uint8Array(key);
}
/**
* Encrypts and authenticates plaintext, authenticates associated data,
* and returns sealed ciphertext, which includes authentication tag.
*
* draft-irtf-cfrg-xchacha-01 defines a 24 byte nonce (192 bits) which
* uses the first 16 bytes of the nonce and the secret key with
* HChaCha to generate an initial subkey. The last 8 bytes of the nonce
* are then prefixed with 4 zero bytes and then provided with the subkey
* to the ChaCha20Poly1305 implementation.
*
* If dst is given (it must be the size of plaintext + the size of tag
* length) the result will be put into it. Dst and plaintext must not
* overlap.
*/
seal(nonce, plaintext, associatedData, dst) {
if (nonce.length !== 24) {
throw new Error("XChaCha20Poly1305: incorrect nonce length");
}
const subKey = hchacha(this._key, nonce.subarray(0, 16), new Uint8Array(32));
const modifiedNonce = new Uint8Array(12);
modifiedNonce.set(nonce.subarray(16), 4);
const chaChaPoly = new ChaCha20Poly1305(subKey);
const result = chaChaPoly.seal(modifiedNonce, plaintext, associatedData, dst);
wipe(subKey);
wipe(modifiedNonce);
chaChaPoly.clean();
return result;
}
/**
* Authenticates sealed ciphertext (which includes authentication tag) and
* associated data, decrypts ciphertext and returns decrypted plaintext.
*
* draft-irtf-cfrg-xchacha-01 defines a 24 byte nonce (192 bits) which
* then uses the first 16 bytes of the nonce and the secret key with
* Hchacha to generate an initial subkey. The last 8 bytes of the nonce
* are then prefixed with 4 zero bytes and then provided with the subkey
* to the chacha20poly1305 implementation.
*
* If authentication fails, it returns null.
*
* If dst is given (it must be the size of plaintext + the size of tag
* length) the result will be put into it. Dst and plaintext must not
* overlap.
*/
open(nonce, sealed, associatedData, dst) {
if (nonce.length !== 24) {
throw new Error("XChaCha20Poly1305: incorrect nonce length");
}
if (sealed.length < this.tagLength) {
return null;
}
const subKey = hchacha(this._key, nonce.subarray(0, 16), new Uint8Array(32));
const modifiedNonce = new Uint8Array(12);
modifiedNonce.set(nonce.subarray(16), 4);
const chaChaPoly = new ChaCha20Poly1305(subKey);
const result = chaChaPoly.open(modifiedNonce, sealed, associatedData, dst);
wipe(subKey);
wipe(modifiedNonce);
chaChaPoly.clean();
return result;
}
clean() {
wipe(this._key);
return this;
}
};
// src/utils/crypto.ts
import { timingSafeEqual as nodeTimingSafeEqual } from "crypto";
function pae(...pieces) {
const output = [];
const lengthBytes = new Uint8Array(8);
const lengthView = new DataView(lengthBytes.buffer);
lengthView.setBigUint64(0, BigInt(pieces.length), true);
output.push(lengthBytes);
for (const piece of pieces) {
const pieceLengthBytes = new Uint8Array(8);
const pieceLengthView = new DataView(pieceLengthBytes.buffer);
pieceLengthView.setBigUint64(0, BigInt(piece.length), true);
output.push(pieceLengthBytes, piece);
}
const totalLength = output.reduce((sum, arr) => sum + arr.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const arr of output) {
result.set(arr, offset);
offset += arr.length;
}
return result;
}
function pack(header, footer, ...pieces) {
const totalLength = pieces.reduce((sum, piece) => sum + piece.length, 0);
const body = new Uint8Array(totalLength);
let offset = 0;
for (const piece of pieces) {
body.set(piece, offset);
offset += piece.length;
}
const bodyBuffer = Buffer.from(body);
const encoded = header + bodyBuffer.toString("base64url");
if (footer.length > 0) {
return encoded + "." + footer.toString("base64url");
}
return encoded;
}
function consume(token, expectedHeader) {
if (!token.startsWith(expectedHeader)) {
throw new Error(`Invalid token header, expected ${expectedHeader}`);
}
const parts = token.split(".");
if (parts.length < 3) {
throw new Error("Invalid token format");
}
const bodyPart = token.slice(expectedHeader.length);
const dotIndex = bodyPart.lastIndexOf(".");
let body;
let footer = Buffer.alloc(0);
if (dotIndex !== -1) {
body = bodyPart.slice(0, dotIndex);
footer = Buffer.from(bodyPart.slice(dotIndex + 1), "base64url");
} else {
body = bodyPart;
}
const raw = Buffer.from(body, "base64url");
return { raw, footer };
}
function timingSafeEqual(a, b) {
if (a.length !== b.length) {
return false;
}
const bufferA = Buffer.from(a);
const bufferB = Buffer.from(b);
return nodeTimingSafeEqual(bufferA, bufferB);
}
// src/v4/utils.ts
import { createSecretKey } from "crypto";
// src/v4/keys.ts
import {
generateKey as cryptoGenerateKey,
generateKeyPair,
createPublicKey,
createPrivateKey,
createSecretKey as cryptoCreateSecretKey
} from "crypto";
import { promisify } from "util";
var generateKeyPairAsync = promisify(generateKeyPair);
var generateSecretKeyAsync = promisify(cryptoGenerateKey);
async function generateKey(purpose, options = { format: "keyobject" }) {
const { format = "keyobject" } = options;
if (format !== "keyobject" && format !== "paserk") {
throw new TypeError('Invalid format, must be "keyobject" or "paserk"');
}
switch (purpose) {
case "local": {
const keyObject = await generateSecretKeyAsync("aes", { length: 256 });
if (format === "paserk") {
return `k4.local.${keyObject.export().toString("base64url")}`;
}
return keyObject;
}
case "public": {
const { privateKey, publicKey } = await generateKeyPairAsync("ed25519");
if (format === "paserk") {
return {
secretKey: `k4.secret.${keyObjectToBytes(privateKey).toString("base64url")}`,
publicKey: `k4.public.${keyObjectToBytes(publicKey).toString("base64url")}`
};
}
return {
privateKey,
publicKey
};
}
default:
throw new PasetoNotSupported(`Unsupported v4 purpose: ${purpose}`);
}
}
function keyObjectToBytes(keyObject) {
if (keyObject.type === "secret") {
return keyObject.export();
}
if (keyObject.asymmetricKeyType === "ed25519") {
if (keyObject.type === "public") {
const jwk = keyObject.export({ format: "jwk" });
return Buffer.from(jwk.x, "base64url");
} else if (keyObject.type === "private") {
const jwk = keyObject.export({ format: "jwk" });
const privateKey = Buffer.from(jwk.d, "base64url");
const publicKey = Buffer.from(jwk.x, "base64url");
return Buffer.concat([privateKey, publicKey]);
}
}
throw new TypeError("Unsupported key type for v4");
}
function bytesToKeyObject(bytes) {
switch (bytes.length) {
case 32:
try {
return createEd25519PublicKey(bytes);
} catch {
return cryptoCreateSecretKey(bytes);
}
case 64:
return createEd25519PrivateKey(bytes);
default:
throw new TypeError(
`Invalid key length: ${bytes.length}. Expected 32 bytes (secret/public key) or 64 bytes (private key)`
);
}
}
function createEd25519PublicKey(bytes) {
const prefix = Buffer.from("302a300506032b6570032100", "hex");
const derKey = Buffer.concat([prefix, bytes]);
return createPublicKey({
key: derKey,
format: "der",
type: "spki"
});
}
function createEd25519PrivateKey(bytes) {
const privateKey = bytes.subarray(0, 32);
const prefix = Buffer.from("302e020100300506032b657004220420", "hex");
const derKey = Buffer.concat([prefix, privateKey]);
return createPrivateKey({
key: derKey,
format: "der",
type: "pkcs8"
});
}
// src/v4/utils.ts
function validateSymmetricKey(key) {
if (typeof key === "string" && key.startsWith("k4.local.")) {
try {
const keyData = Buffer.from(key.slice(9), "base64url");
if (keyData.length !== 32) {
throw new Error("Invalid key length");
}
return createSecretKey(keyData);
} catch {
throw new TypeError("Invalid PASERK k4.local key format");
}
}
if (Buffer.isBuffer(key)) {
if (key.length !== 32) {
throw new TypeError("v4.local symmetric key must be exactly 32 bytes");
}
return createSecretKey(key);
}
if (isKeyObject(key)) {
if (key.type !== "secret" || key.symmetricKeySize !== 32) {
throw new TypeError("v4.local symmetric key must be a 32-byte secret key");
}
return key;
}
throw new TypeError("Invalid symmetric key format for v4.local - must be PASERK string, Buffer, or KeyObject");
}
function processPayload(payload, options = {}) {
if (Buffer.isBuffer(payload)) {
return payload;
}
const claims = { ...payload };
const now = options.now || /* @__PURE__ */ new Date();
if (options.iat === true) {
claims.iat = Math.floor(now.getTime() / 1e3);
}
if (options.expiresIn) {
const expiration = parseTimespan(options.expiresIn);
claims.exp = Math.floor((now.getTime() + expiration) / 1e3);
}
if (options.notBefore) {
const notBefore = parseTimespan(options.notBefore);
claims.nbf = Math.floor((now.getTime() + notBefore) / 1e3);
}
if (options.audience) claims.aud = options.audience;
if (options.issuer) claims.iss = options.issuer;