@kangentic/protocol 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.md +27 -0
- package/dist/capabilities/verbs.d.ts +18 -0
- package/dist/crypto/noise/cipher-state.d.ts +9 -0
- package/dist/crypto/noise/handshake-state.d.ts +64 -0
- package/dist/crypto/noise/kk.d.ts +11 -0
- package/dist/crypto/noise/patterns.d.ts +48 -0
- package/dist/crypto/noise/symmetric-state.d.ts +28 -0
- package/dist/crypto/pairing-handshake.d.ts +20 -0
- package/dist/crypto/primitives.d.ts +53 -0
- package/dist/crypto/sas.d.ts +7 -0
- package/dist/crypto/secretstream.d.ts +39 -0
- package/dist/events/event.d.ts +29 -0
- package/dist/index.cjs +4571 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.mjs +4504 -0
- package/dist/pairing/qr.d.ts +19 -0
- package/dist/roster/roster.d.ts +33 -0
- package/dist/transport/transport.d.ts +22 -0
- package/dist/version.d.ts +12 -0
- package/dist/wire/base64url.d.ts +2 -0
- package/dist/wire/framing.d.ts +4 -0
- package/dist/wire/messages.d.ts +45 -0
- package/dist/wire/session-frame.d.ts +23 -0
- package/package.json +51 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,4571 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
CAPABILITY_VERBS: () => CAPABILITY_VERBS,
|
|
24
|
+
CipherState: () => CipherState,
|
|
25
|
+
ED25519_KEY_LENGTH: () => ED25519_KEY_LENGTH,
|
|
26
|
+
FrameTag: () => FrameTag,
|
|
27
|
+
HandshakeState: () => HandshakeState,
|
|
28
|
+
IKPSK0_PATTERN: () => IKPSK0_PATTERN,
|
|
29
|
+
KK_PATTERN: () => KK_PATTERN,
|
|
30
|
+
MAX_FRAME_LENGTH: () => MAX_FRAME_LENGTH,
|
|
31
|
+
PAIRING_URI_SCHEME: () => PAIRING_URI_SCHEME,
|
|
32
|
+
PROTOCOL_VERSION: () => PROTOCOL_VERSION,
|
|
33
|
+
SecretstreamState: () => SecretstreamState,
|
|
34
|
+
SessionFrameKind: () => SessionFrameKind,
|
|
35
|
+
X25519_KEY_LENGTH: () => X25519_KEY_LENGTH,
|
|
36
|
+
bytesToHex: () => bytesToHex,
|
|
37
|
+
capabilitySetFromArray: () => capabilitySetFromArray,
|
|
38
|
+
capabilitySetToArray: () => capabilitySetToArray,
|
|
39
|
+
capabilitySetToRosterCapabilities: () => capabilitySetToRosterCapabilities,
|
|
40
|
+
createKKHandshake: () => createKKHandshake,
|
|
41
|
+
createPairingInitiatorHandshake: () => createPairingInitiatorHandshake,
|
|
42
|
+
createPairingResponderHandshake: () => createPairingResponderHandshake,
|
|
43
|
+
decodeMessage: () => decodeMessage,
|
|
44
|
+
decodePairingQrPayload: () => decodePairingQrPayload,
|
|
45
|
+
deriveSecretstreamPair: () => deriveSecretstreamPair,
|
|
46
|
+
deriveShortAuthenticationString: () => deriveShortAuthenticationString,
|
|
47
|
+
encodeMessage: () => encodeMessage,
|
|
48
|
+
encodePairingQrPayload: () => encodePairingQrPayload,
|
|
49
|
+
encodeProtocolVersion: () => encodeProtocolVersion,
|
|
50
|
+
encodeRosterEntryForSigning: () => encodeRosterEntryForSigning,
|
|
51
|
+
findRosterDevice: () => findRosterDevice,
|
|
52
|
+
generateEd25519KeyPair: () => generateEd25519KeyPair,
|
|
53
|
+
generateX25519KeyPair: () => generateX25519KeyPair,
|
|
54
|
+
hexToBytes: () => hexToBytes,
|
|
55
|
+
isCapabilityVerb: () => isCapabilityVerb,
|
|
56
|
+
isRosterEntryExpired: () => isRosterEntryExpired,
|
|
57
|
+
randomBytes: () => randomBytes4,
|
|
58
|
+
rosterDeviceCapabilitySet: () => rosterDeviceCapabilitySet,
|
|
59
|
+
signRosterEntry: () => signRosterEntry,
|
|
60
|
+
unwrapSessionFrame: () => unwrapSessionFrame,
|
|
61
|
+
verifyRosterEntry: () => verifyRosterEntry,
|
|
62
|
+
wrapSessionFrame: () => wrapSessionFrame,
|
|
63
|
+
x25519PublicKeyFrom: () => x25519PublicKeyFrom
|
|
64
|
+
});
|
|
65
|
+
module.exports = __toCommonJS(index_exports);
|
|
66
|
+
|
|
67
|
+
// src/version.ts
|
|
68
|
+
var PROTOCOL_VERSION = "1";
|
|
69
|
+
function encodeProtocolVersion(version = PROTOCOL_VERSION) {
|
|
70
|
+
return new TextEncoder().encode(`kangentic-bridge-v${version}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ../../node_modules/@noble/hashes/utils.js
|
|
74
|
+
function isBytes(a) {
|
|
75
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
76
|
+
}
|
|
77
|
+
function anumber(n, title = "") {
|
|
78
|
+
if (typeof n !== "number") {
|
|
79
|
+
const prefix = title && `"${title}" `;
|
|
80
|
+
throw new TypeError(`${prefix}expected number, got ${typeof n}`);
|
|
81
|
+
}
|
|
82
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
83
|
+
const prefix = title && `"${title}" `;
|
|
84
|
+
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function abytes(value, length, title = "") {
|
|
88
|
+
const bytes = isBytes(value);
|
|
89
|
+
const len = value?.length;
|
|
90
|
+
const needsLen = length !== void 0;
|
|
91
|
+
if (!bytes || needsLen && len !== length) {
|
|
92
|
+
const prefix = title && `"${title}" `;
|
|
93
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
94
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
95
|
+
const message = prefix + "expected Uint8Array" + ofLen + ", got " + got;
|
|
96
|
+
if (!bytes)
|
|
97
|
+
throw new TypeError(message);
|
|
98
|
+
throw new RangeError(message);
|
|
99
|
+
}
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
function ahash(h) {
|
|
103
|
+
if (typeof h !== "function" || typeof h.create !== "function")
|
|
104
|
+
throw new TypeError("Hash must wrapped by utils.createHasher");
|
|
105
|
+
anumber(h.outputLen);
|
|
106
|
+
anumber(h.blockLen);
|
|
107
|
+
if (h.outputLen < 1)
|
|
108
|
+
throw new Error('"outputLen" must be >= 1');
|
|
109
|
+
if (h.blockLen < 1)
|
|
110
|
+
throw new Error('"blockLen" must be >= 1');
|
|
111
|
+
}
|
|
112
|
+
function aexists(instance, checkFinished = true) {
|
|
113
|
+
if (instance.destroyed)
|
|
114
|
+
throw new Error("Hash instance has been destroyed");
|
|
115
|
+
if (checkFinished && instance.finished)
|
|
116
|
+
throw new Error("Hash#digest() has already been called");
|
|
117
|
+
}
|
|
118
|
+
function aoutput(out, instance) {
|
|
119
|
+
abytes(out, void 0, "digestInto() output");
|
|
120
|
+
const min = instance.outputLen;
|
|
121
|
+
if (out.length < min) {
|
|
122
|
+
throw new RangeError('"digestInto() output" expected to be of length >=' + min);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function u32(arr) {
|
|
126
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
127
|
+
}
|
|
128
|
+
function clean(...arrays) {
|
|
129
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
130
|
+
arrays[i].fill(0);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function createView(arr) {
|
|
134
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
135
|
+
}
|
|
136
|
+
function rotr(word, shift) {
|
|
137
|
+
return word << 32 - shift | word >>> shift;
|
|
138
|
+
}
|
|
139
|
+
var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
140
|
+
function byteSwap(word) {
|
|
141
|
+
return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
142
|
+
}
|
|
143
|
+
var swap8IfBE = isLE ? (n) => n : (n) => byteSwap(n) >>> 0;
|
|
144
|
+
function byteSwap32(arr) {
|
|
145
|
+
for (let i = 0; i < arr.length; i++) {
|
|
146
|
+
arr[i] = byteSwap(arr[i]);
|
|
147
|
+
}
|
|
148
|
+
return arr;
|
|
149
|
+
}
|
|
150
|
+
var swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
151
|
+
var hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
|
|
154
|
+
))();
|
|
155
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
156
|
+
function bytesToHex(bytes) {
|
|
157
|
+
abytes(bytes);
|
|
158
|
+
if (hasHexBuiltin)
|
|
159
|
+
return bytes.toHex();
|
|
160
|
+
let hex = "";
|
|
161
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
162
|
+
hex += hexes[bytes[i]];
|
|
163
|
+
}
|
|
164
|
+
return hex;
|
|
165
|
+
}
|
|
166
|
+
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
167
|
+
function asciiToBase16(ch) {
|
|
168
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
169
|
+
return ch - asciis._0;
|
|
170
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
171
|
+
return ch - (asciis.A - 10);
|
|
172
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
173
|
+
return ch - (asciis.a - 10);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
function hexToBytes(hex) {
|
|
177
|
+
if (typeof hex !== "string")
|
|
178
|
+
throw new TypeError("hex string expected, got " + typeof hex);
|
|
179
|
+
if (hasHexBuiltin) {
|
|
180
|
+
try {
|
|
181
|
+
return Uint8Array.fromHex(hex);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
if (error instanceof SyntaxError)
|
|
184
|
+
throw new RangeError(error.message);
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const hl = hex.length;
|
|
189
|
+
const al = hl / 2;
|
|
190
|
+
if (hl % 2)
|
|
191
|
+
throw new RangeError("hex string expected, got unpadded hex of length " + hl);
|
|
192
|
+
const array = new Uint8Array(al);
|
|
193
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
194
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
195
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
196
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
197
|
+
const char = hex[hi] + hex[hi + 1];
|
|
198
|
+
throw new RangeError('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
199
|
+
}
|
|
200
|
+
array[ai] = n1 * 16 + n2;
|
|
201
|
+
}
|
|
202
|
+
return array;
|
|
203
|
+
}
|
|
204
|
+
function concatBytes(...arrays) {
|
|
205
|
+
let sum = 0;
|
|
206
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
207
|
+
const a = arrays[i];
|
|
208
|
+
abytes(a);
|
|
209
|
+
sum += a.length;
|
|
210
|
+
}
|
|
211
|
+
const res = new Uint8Array(sum);
|
|
212
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
213
|
+
const a = arrays[i];
|
|
214
|
+
res.set(a, pad);
|
|
215
|
+
pad += a.length;
|
|
216
|
+
}
|
|
217
|
+
return res;
|
|
218
|
+
}
|
|
219
|
+
function createHasher(hashCons, info = {}) {
|
|
220
|
+
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
221
|
+
const tmp = hashCons(void 0);
|
|
222
|
+
hashC.outputLen = tmp.outputLen;
|
|
223
|
+
hashC.blockLen = tmp.blockLen;
|
|
224
|
+
hashC.canXOF = tmp.canXOF;
|
|
225
|
+
hashC.create = (opts) => hashCons(opts);
|
|
226
|
+
Object.assign(hashC, info);
|
|
227
|
+
return Object.freeze(hashC);
|
|
228
|
+
}
|
|
229
|
+
function randomBytes(bytesLength = 32) {
|
|
230
|
+
anumber(bytesLength, "bytesLength");
|
|
231
|
+
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
232
|
+
if (typeof cr?.getRandomValues !== "function")
|
|
233
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
234
|
+
if (bytesLength > 65536)
|
|
235
|
+
throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`);
|
|
236
|
+
return cr.getRandomValues(new Uint8Array(bytesLength));
|
|
237
|
+
}
|
|
238
|
+
var oidNist = (suffix) => ({
|
|
239
|
+
// Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.
|
|
240
|
+
// Larger suffix values would need base-128 OID encoding and a different length byte.
|
|
241
|
+
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// ../../node_modules/@noble/hashes/_md.js
|
|
245
|
+
var HashMD = class {
|
|
246
|
+
blockLen;
|
|
247
|
+
outputLen;
|
|
248
|
+
canXOF = false;
|
|
249
|
+
padOffset;
|
|
250
|
+
isLE;
|
|
251
|
+
// For partial updates less than block size
|
|
252
|
+
buffer;
|
|
253
|
+
view;
|
|
254
|
+
finished = false;
|
|
255
|
+
length = 0;
|
|
256
|
+
pos = 0;
|
|
257
|
+
destroyed = false;
|
|
258
|
+
constructor(blockLen, outputLen, padOffset, isLE3) {
|
|
259
|
+
this.blockLen = blockLen;
|
|
260
|
+
this.outputLen = outputLen;
|
|
261
|
+
this.padOffset = padOffset;
|
|
262
|
+
this.isLE = isLE3;
|
|
263
|
+
this.buffer = new Uint8Array(blockLen);
|
|
264
|
+
this.view = createView(this.buffer);
|
|
265
|
+
}
|
|
266
|
+
update(data) {
|
|
267
|
+
aexists(this);
|
|
268
|
+
abytes(data);
|
|
269
|
+
const { view, buffer, blockLen } = this;
|
|
270
|
+
const len = data.length;
|
|
271
|
+
for (let pos = 0; pos < len; ) {
|
|
272
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
273
|
+
if (take === blockLen) {
|
|
274
|
+
const dataView = createView(data);
|
|
275
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
276
|
+
this.process(dataView, pos);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
280
|
+
this.pos += take;
|
|
281
|
+
pos += take;
|
|
282
|
+
if (this.pos === blockLen) {
|
|
283
|
+
this.process(view, 0);
|
|
284
|
+
this.pos = 0;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
this.length += data.length;
|
|
288
|
+
this.roundClean();
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
digestInto(out) {
|
|
292
|
+
aexists(this);
|
|
293
|
+
aoutput(out, this);
|
|
294
|
+
this.finished = true;
|
|
295
|
+
const { buffer, view, blockLen, isLE: isLE3 } = this;
|
|
296
|
+
let { pos } = this;
|
|
297
|
+
buffer[pos++] = 128;
|
|
298
|
+
clean(this.buffer.subarray(pos));
|
|
299
|
+
if (this.padOffset > blockLen - pos) {
|
|
300
|
+
this.process(view, 0);
|
|
301
|
+
pos = 0;
|
|
302
|
+
}
|
|
303
|
+
for (let i = pos; i < blockLen; i++)
|
|
304
|
+
buffer[i] = 0;
|
|
305
|
+
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE3);
|
|
306
|
+
this.process(view, 0);
|
|
307
|
+
const oview = createView(out);
|
|
308
|
+
const len = this.outputLen;
|
|
309
|
+
if (len % 4)
|
|
310
|
+
throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
311
|
+
const outLen = len / 4;
|
|
312
|
+
const state = this.get();
|
|
313
|
+
if (outLen > state.length)
|
|
314
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
315
|
+
for (let i = 0; i < outLen; i++)
|
|
316
|
+
oview.setUint32(4 * i, state[i], isLE3);
|
|
317
|
+
}
|
|
318
|
+
digest() {
|
|
319
|
+
const { buffer, outputLen } = this;
|
|
320
|
+
this.digestInto(buffer);
|
|
321
|
+
const res = buffer.slice(0, outputLen);
|
|
322
|
+
this.destroy();
|
|
323
|
+
return res;
|
|
324
|
+
}
|
|
325
|
+
_cloneInto(to) {
|
|
326
|
+
to ||= new this.constructor();
|
|
327
|
+
to.set(...this.get());
|
|
328
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
329
|
+
to.destroyed = destroyed;
|
|
330
|
+
to.finished = finished;
|
|
331
|
+
to.length = length;
|
|
332
|
+
to.pos = pos;
|
|
333
|
+
if (length % blockLen)
|
|
334
|
+
to.buffer.set(buffer);
|
|
335
|
+
return to;
|
|
336
|
+
}
|
|
337
|
+
clone() {
|
|
338
|
+
return this._cloneInto();
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
342
|
+
1779033703,
|
|
343
|
+
3144134277,
|
|
344
|
+
1013904242,
|
|
345
|
+
2773480762,
|
|
346
|
+
1359893119,
|
|
347
|
+
2600822924,
|
|
348
|
+
528734635,
|
|
349
|
+
1541459225
|
|
350
|
+
]);
|
|
351
|
+
var SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
352
|
+
1779033703,
|
|
353
|
+
4089235720,
|
|
354
|
+
3144134277,
|
|
355
|
+
2227873595,
|
|
356
|
+
1013904242,
|
|
357
|
+
4271175723,
|
|
358
|
+
2773480762,
|
|
359
|
+
1595750129,
|
|
360
|
+
1359893119,
|
|
361
|
+
2917565137,
|
|
362
|
+
2600822924,
|
|
363
|
+
725511199,
|
|
364
|
+
528734635,
|
|
365
|
+
4215389547,
|
|
366
|
+
1541459225,
|
|
367
|
+
327033209
|
|
368
|
+
]);
|
|
369
|
+
|
|
370
|
+
// ../../node_modules/@noble/hashes/_u64.js
|
|
371
|
+
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
372
|
+
var _32n = /* @__PURE__ */ BigInt(32);
|
|
373
|
+
function fromBig(n, le = false) {
|
|
374
|
+
if (le)
|
|
375
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
376
|
+
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
377
|
+
}
|
|
378
|
+
function split(lst, le = false) {
|
|
379
|
+
const len = lst.length;
|
|
380
|
+
let Ah = new Uint32Array(len);
|
|
381
|
+
let Al = new Uint32Array(len);
|
|
382
|
+
for (let i = 0; i < len; i++) {
|
|
383
|
+
const { h, l } = fromBig(lst[i], le);
|
|
384
|
+
[Ah[i], Al[i]] = [h, l];
|
|
385
|
+
}
|
|
386
|
+
return [Ah, Al];
|
|
387
|
+
}
|
|
388
|
+
var shrSH = (h, _l, s) => h >>> s;
|
|
389
|
+
var shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
390
|
+
var rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
391
|
+
var rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
392
|
+
var rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
393
|
+
var rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
394
|
+
function add(Ah, Al, Bh, Bl) {
|
|
395
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
396
|
+
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
397
|
+
}
|
|
398
|
+
var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
399
|
+
var add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
400
|
+
var add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
401
|
+
var add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
402
|
+
var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
403
|
+
var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
404
|
+
|
|
405
|
+
// ../../node_modules/@noble/hashes/sha2.js
|
|
406
|
+
var K512 = /* @__PURE__ */ (() => split([
|
|
407
|
+
"0x428a2f98d728ae22",
|
|
408
|
+
"0x7137449123ef65cd",
|
|
409
|
+
"0xb5c0fbcfec4d3b2f",
|
|
410
|
+
"0xe9b5dba58189dbbc",
|
|
411
|
+
"0x3956c25bf348b538",
|
|
412
|
+
"0x59f111f1b605d019",
|
|
413
|
+
"0x923f82a4af194f9b",
|
|
414
|
+
"0xab1c5ed5da6d8118",
|
|
415
|
+
"0xd807aa98a3030242",
|
|
416
|
+
"0x12835b0145706fbe",
|
|
417
|
+
"0x243185be4ee4b28c",
|
|
418
|
+
"0x550c7dc3d5ffb4e2",
|
|
419
|
+
"0x72be5d74f27b896f",
|
|
420
|
+
"0x80deb1fe3b1696b1",
|
|
421
|
+
"0x9bdc06a725c71235",
|
|
422
|
+
"0xc19bf174cf692694",
|
|
423
|
+
"0xe49b69c19ef14ad2",
|
|
424
|
+
"0xefbe4786384f25e3",
|
|
425
|
+
"0x0fc19dc68b8cd5b5",
|
|
426
|
+
"0x240ca1cc77ac9c65",
|
|
427
|
+
"0x2de92c6f592b0275",
|
|
428
|
+
"0x4a7484aa6ea6e483",
|
|
429
|
+
"0x5cb0a9dcbd41fbd4",
|
|
430
|
+
"0x76f988da831153b5",
|
|
431
|
+
"0x983e5152ee66dfab",
|
|
432
|
+
"0xa831c66d2db43210",
|
|
433
|
+
"0xb00327c898fb213f",
|
|
434
|
+
"0xbf597fc7beef0ee4",
|
|
435
|
+
"0xc6e00bf33da88fc2",
|
|
436
|
+
"0xd5a79147930aa725",
|
|
437
|
+
"0x06ca6351e003826f",
|
|
438
|
+
"0x142929670a0e6e70",
|
|
439
|
+
"0x27b70a8546d22ffc",
|
|
440
|
+
"0x2e1b21385c26c926",
|
|
441
|
+
"0x4d2c6dfc5ac42aed",
|
|
442
|
+
"0x53380d139d95b3df",
|
|
443
|
+
"0x650a73548baf63de",
|
|
444
|
+
"0x766a0abb3c77b2a8",
|
|
445
|
+
"0x81c2c92e47edaee6",
|
|
446
|
+
"0x92722c851482353b",
|
|
447
|
+
"0xa2bfe8a14cf10364",
|
|
448
|
+
"0xa81a664bbc423001",
|
|
449
|
+
"0xc24b8b70d0f89791",
|
|
450
|
+
"0xc76c51a30654be30",
|
|
451
|
+
"0xd192e819d6ef5218",
|
|
452
|
+
"0xd69906245565a910",
|
|
453
|
+
"0xf40e35855771202a",
|
|
454
|
+
"0x106aa07032bbd1b8",
|
|
455
|
+
"0x19a4c116b8d2d0c8",
|
|
456
|
+
"0x1e376c085141ab53",
|
|
457
|
+
"0x2748774cdf8eeb99",
|
|
458
|
+
"0x34b0bcb5e19b48a8",
|
|
459
|
+
"0x391c0cb3c5c95a63",
|
|
460
|
+
"0x4ed8aa4ae3418acb",
|
|
461
|
+
"0x5b9cca4f7763e373",
|
|
462
|
+
"0x682e6ff3d6b2b8a3",
|
|
463
|
+
"0x748f82ee5defb2fc",
|
|
464
|
+
"0x78a5636f43172f60",
|
|
465
|
+
"0x84c87814a1f0ab72",
|
|
466
|
+
"0x8cc702081a6439ec",
|
|
467
|
+
"0x90befffa23631e28",
|
|
468
|
+
"0xa4506cebde82bde9",
|
|
469
|
+
"0xbef9a3f7b2c67915",
|
|
470
|
+
"0xc67178f2e372532b",
|
|
471
|
+
"0xca273eceea26619c",
|
|
472
|
+
"0xd186b8c721c0c207",
|
|
473
|
+
"0xeada7dd6cde0eb1e",
|
|
474
|
+
"0xf57d4f7fee6ed178",
|
|
475
|
+
"0x06f067aa72176fba",
|
|
476
|
+
"0x0a637dc5a2c898a6",
|
|
477
|
+
"0x113f9804bef90dae",
|
|
478
|
+
"0x1b710b35131c471b",
|
|
479
|
+
"0x28db77f523047d84",
|
|
480
|
+
"0x32caab7b40c72493",
|
|
481
|
+
"0x3c9ebe0a15c9bebc",
|
|
482
|
+
"0x431d67c49c100d4c",
|
|
483
|
+
"0x4cc5d4becb3e42b6",
|
|
484
|
+
"0x597f299cfc657e2a",
|
|
485
|
+
"0x5fcb6fab3ad6faec",
|
|
486
|
+
"0x6c44198c4a475817"
|
|
487
|
+
].map((n) => BigInt(n))))();
|
|
488
|
+
var SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
|
489
|
+
var SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
490
|
+
var SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
491
|
+
var SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
492
|
+
var SHA2_64B = class extends HashMD {
|
|
493
|
+
constructor(outputLen) {
|
|
494
|
+
super(128, outputLen, 16, false);
|
|
495
|
+
}
|
|
496
|
+
// prettier-ignore
|
|
497
|
+
get() {
|
|
498
|
+
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
499
|
+
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
|
500
|
+
}
|
|
501
|
+
// prettier-ignore
|
|
502
|
+
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
|
503
|
+
this.Ah = Ah | 0;
|
|
504
|
+
this.Al = Al | 0;
|
|
505
|
+
this.Bh = Bh | 0;
|
|
506
|
+
this.Bl = Bl | 0;
|
|
507
|
+
this.Ch = Ch | 0;
|
|
508
|
+
this.Cl = Cl | 0;
|
|
509
|
+
this.Dh = Dh | 0;
|
|
510
|
+
this.Dl = Dl | 0;
|
|
511
|
+
this.Eh = Eh | 0;
|
|
512
|
+
this.El = El | 0;
|
|
513
|
+
this.Fh = Fh | 0;
|
|
514
|
+
this.Fl = Fl | 0;
|
|
515
|
+
this.Gh = Gh | 0;
|
|
516
|
+
this.Gl = Gl | 0;
|
|
517
|
+
this.Hh = Hh | 0;
|
|
518
|
+
this.Hl = Hl | 0;
|
|
519
|
+
}
|
|
520
|
+
process(view, offset) {
|
|
521
|
+
for (let i = 0; i < 16; i++, offset += 4) {
|
|
522
|
+
SHA512_W_H[i] = view.getUint32(offset);
|
|
523
|
+
SHA512_W_L[i] = view.getUint32(offset += 4);
|
|
524
|
+
}
|
|
525
|
+
for (let i = 16; i < 80; i++) {
|
|
526
|
+
const W15h = SHA512_W_H[i - 15] | 0;
|
|
527
|
+
const W15l = SHA512_W_L[i - 15] | 0;
|
|
528
|
+
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
529
|
+
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
530
|
+
const W2h = SHA512_W_H[i - 2] | 0;
|
|
531
|
+
const W2l = SHA512_W_L[i - 2] | 0;
|
|
532
|
+
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
533
|
+
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
534
|
+
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
535
|
+
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
|
536
|
+
SHA512_W_H[i] = SUMh | 0;
|
|
537
|
+
SHA512_W_L[i] = SUMl | 0;
|
|
538
|
+
}
|
|
539
|
+
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
540
|
+
for (let i = 0; i < 80; i++) {
|
|
541
|
+
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
542
|
+
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
543
|
+
const CHIh = Eh & Fh ^ ~Eh & Gh;
|
|
544
|
+
const CHIl = El & Fl ^ ~El & Gl;
|
|
545
|
+
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
546
|
+
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
547
|
+
const T1l = T1ll | 0;
|
|
548
|
+
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
549
|
+
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
550
|
+
const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
|
|
551
|
+
const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
|
|
552
|
+
Hh = Gh | 0;
|
|
553
|
+
Hl = Gl | 0;
|
|
554
|
+
Gh = Fh | 0;
|
|
555
|
+
Gl = Fl | 0;
|
|
556
|
+
Fh = Eh | 0;
|
|
557
|
+
Fl = El | 0;
|
|
558
|
+
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
559
|
+
Dh = Ch | 0;
|
|
560
|
+
Dl = Cl | 0;
|
|
561
|
+
Ch = Bh | 0;
|
|
562
|
+
Cl = Bl | 0;
|
|
563
|
+
Bh = Ah | 0;
|
|
564
|
+
Bl = Al | 0;
|
|
565
|
+
const All = add3L(T1l, sigma0l, MAJl);
|
|
566
|
+
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
567
|
+
Al = All | 0;
|
|
568
|
+
}
|
|
569
|
+
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
570
|
+
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
571
|
+
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
572
|
+
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
573
|
+
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
574
|
+
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
575
|
+
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
576
|
+
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
577
|
+
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
578
|
+
}
|
|
579
|
+
roundClean() {
|
|
580
|
+
clean(SHA512_W_H, SHA512_W_L);
|
|
581
|
+
}
|
|
582
|
+
destroy() {
|
|
583
|
+
this.destroyed = true;
|
|
584
|
+
clean(this.buffer);
|
|
585
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
var _SHA512 = class extends SHA2_64B {
|
|
589
|
+
Ah = SHA512_IV[0] | 0;
|
|
590
|
+
Al = SHA512_IV[1] | 0;
|
|
591
|
+
Bh = SHA512_IV[2] | 0;
|
|
592
|
+
Bl = SHA512_IV[3] | 0;
|
|
593
|
+
Ch = SHA512_IV[4] | 0;
|
|
594
|
+
Cl = SHA512_IV[5] | 0;
|
|
595
|
+
Dh = SHA512_IV[6] | 0;
|
|
596
|
+
Dl = SHA512_IV[7] | 0;
|
|
597
|
+
Eh = SHA512_IV[8] | 0;
|
|
598
|
+
El = SHA512_IV[9] | 0;
|
|
599
|
+
Fh = SHA512_IV[10] | 0;
|
|
600
|
+
Fl = SHA512_IV[11] | 0;
|
|
601
|
+
Gh = SHA512_IV[12] | 0;
|
|
602
|
+
Gl = SHA512_IV[13] | 0;
|
|
603
|
+
Hh = SHA512_IV[14] | 0;
|
|
604
|
+
Hl = SHA512_IV[15] | 0;
|
|
605
|
+
constructor() {
|
|
606
|
+
super(64);
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
var sha512 = /* @__PURE__ */ createHasher(
|
|
610
|
+
() => new _SHA512(),
|
|
611
|
+
/* @__PURE__ */ oidNist(3)
|
|
612
|
+
);
|
|
613
|
+
|
|
614
|
+
// ../../node_modules/@noble/curves/utils.js
|
|
615
|
+
var abytes2 = (value, length, title) => abytes(value, length, title);
|
|
616
|
+
var anumber2 = anumber;
|
|
617
|
+
var bytesToHex2 = bytesToHex;
|
|
618
|
+
var concatBytes2 = (...arrays) => concatBytes(...arrays);
|
|
619
|
+
var hexToBytes2 = (hex) => hexToBytes(hex);
|
|
620
|
+
var isBytes2 = isBytes;
|
|
621
|
+
var randomBytes2 = (bytesLength) => randomBytes(bytesLength);
|
|
622
|
+
var _0n = /* @__PURE__ */ BigInt(0);
|
|
623
|
+
var _1n = /* @__PURE__ */ BigInt(1);
|
|
624
|
+
function abool(value, title = "") {
|
|
625
|
+
if (typeof value !== "boolean") {
|
|
626
|
+
const prefix = title && `"${title}" `;
|
|
627
|
+
throw new TypeError(prefix + "expected boolean, got type=" + typeof value);
|
|
628
|
+
}
|
|
629
|
+
return value;
|
|
630
|
+
}
|
|
631
|
+
function abignumber(n) {
|
|
632
|
+
if (typeof n === "bigint") {
|
|
633
|
+
if (!isPosBig(n))
|
|
634
|
+
throw new RangeError("positive bigint expected, got " + n);
|
|
635
|
+
} else
|
|
636
|
+
anumber2(n);
|
|
637
|
+
return n;
|
|
638
|
+
}
|
|
639
|
+
function asafenumber(value, title = "") {
|
|
640
|
+
if (typeof value !== "number") {
|
|
641
|
+
const prefix = title && `"${title}" `;
|
|
642
|
+
throw new TypeError(prefix + "expected number, got type=" + typeof value);
|
|
643
|
+
}
|
|
644
|
+
if (!Number.isSafeInteger(value)) {
|
|
645
|
+
const prefix = title && `"${title}" `;
|
|
646
|
+
throw new RangeError(prefix + "expected safe integer, got " + value);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
function hexToNumber(hex) {
|
|
650
|
+
if (typeof hex !== "string")
|
|
651
|
+
throw new TypeError("hex string expected, got " + typeof hex);
|
|
652
|
+
return hex === "" ? _0n : BigInt("0x" + hex);
|
|
653
|
+
}
|
|
654
|
+
function bytesToNumberBE(bytes) {
|
|
655
|
+
return hexToNumber(bytesToHex(bytes));
|
|
656
|
+
}
|
|
657
|
+
function bytesToNumberLE(bytes) {
|
|
658
|
+
return hexToNumber(bytesToHex(copyBytes(abytes(bytes)).reverse()));
|
|
659
|
+
}
|
|
660
|
+
function numberToBytesBE(n, len) {
|
|
661
|
+
anumber(len);
|
|
662
|
+
if (len === 0)
|
|
663
|
+
throw new RangeError("zero length");
|
|
664
|
+
n = abignumber(n);
|
|
665
|
+
const hex = n.toString(16);
|
|
666
|
+
if (hex.length > len * 2)
|
|
667
|
+
throw new RangeError("number too large");
|
|
668
|
+
return hexToBytes(hex.padStart(len * 2, "0"));
|
|
669
|
+
}
|
|
670
|
+
function numberToBytesLE(n, len) {
|
|
671
|
+
return numberToBytesBE(n, len).reverse();
|
|
672
|
+
}
|
|
673
|
+
function equalBytes(a, b) {
|
|
674
|
+
a = abytes2(a);
|
|
675
|
+
b = abytes2(b);
|
|
676
|
+
if (a.length !== b.length)
|
|
677
|
+
return false;
|
|
678
|
+
let diff = 0;
|
|
679
|
+
for (let i = 0; i < a.length; i++)
|
|
680
|
+
diff |= a[i] ^ b[i];
|
|
681
|
+
return diff === 0;
|
|
682
|
+
}
|
|
683
|
+
function copyBytes(bytes) {
|
|
684
|
+
return Uint8Array.from(abytes2(bytes));
|
|
685
|
+
}
|
|
686
|
+
function asciiToBytes(ascii) {
|
|
687
|
+
if (typeof ascii !== "string")
|
|
688
|
+
throw new TypeError("ascii string expected, got " + typeof ascii);
|
|
689
|
+
return Uint8Array.from(ascii, (c, i) => {
|
|
690
|
+
const charCode = c.charCodeAt(0);
|
|
691
|
+
if (c.length !== 1 || charCode > 127) {
|
|
692
|
+
throw new RangeError(`string contains non-ASCII character "${ascii[i]}" with code ${charCode} at position ${i}`);
|
|
693
|
+
}
|
|
694
|
+
return charCode;
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
698
|
+
function inRange(n, min, max) {
|
|
699
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
700
|
+
}
|
|
701
|
+
function aInRange(title, n, min, max) {
|
|
702
|
+
if (!inRange(n, min, max))
|
|
703
|
+
throw new RangeError("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
704
|
+
}
|
|
705
|
+
function bitLen(n) {
|
|
706
|
+
if (n < _0n)
|
|
707
|
+
throw new Error("expected non-negative bigint, got " + n);
|
|
708
|
+
let len;
|
|
709
|
+
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
710
|
+
;
|
|
711
|
+
return len;
|
|
712
|
+
}
|
|
713
|
+
var bitMask = (n) => (_1n << BigInt(n)) - _1n;
|
|
714
|
+
function validateObject(object, fields = {}, optFields = {}) {
|
|
715
|
+
if (Object.prototype.toString.call(object) !== "[object Object]")
|
|
716
|
+
throw new TypeError("expected valid options object");
|
|
717
|
+
function checkField(fieldName, expectedType, isOpt) {
|
|
718
|
+
if (!isOpt && expectedType !== "function" && !Object.hasOwn(object, fieldName))
|
|
719
|
+
throw new TypeError(`param "${fieldName}" is invalid: expected own property`);
|
|
720
|
+
const val = object[fieldName];
|
|
721
|
+
if (isOpt && val === void 0)
|
|
722
|
+
return;
|
|
723
|
+
const current = typeof val;
|
|
724
|
+
if (current !== expectedType || val === null)
|
|
725
|
+
throw new TypeError(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
726
|
+
}
|
|
727
|
+
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
|
|
728
|
+
iter(fields, false);
|
|
729
|
+
iter(optFields, true);
|
|
730
|
+
}
|
|
731
|
+
var notImplemented = () => {
|
|
732
|
+
throw new Error("not implemented");
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
// ../../node_modules/@noble/curves/abstract/modular.js
|
|
736
|
+
var _0n2 = /* @__PURE__ */ BigInt(0);
|
|
737
|
+
var _1n2 = /* @__PURE__ */ BigInt(1);
|
|
738
|
+
var _2n = /* @__PURE__ */ BigInt(2);
|
|
739
|
+
var _3n = /* @__PURE__ */ BigInt(3);
|
|
740
|
+
var _4n = /* @__PURE__ */ BigInt(4);
|
|
741
|
+
var _5n = /* @__PURE__ */ BigInt(5);
|
|
742
|
+
var _7n = /* @__PURE__ */ BigInt(7);
|
|
743
|
+
var _8n = /* @__PURE__ */ BigInt(8);
|
|
744
|
+
var _9n = /* @__PURE__ */ BigInt(9);
|
|
745
|
+
var _16n = /* @__PURE__ */ BigInt(16);
|
|
746
|
+
function mod(a, b) {
|
|
747
|
+
if (b <= _0n2)
|
|
748
|
+
throw new Error("mod: expected positive modulus, got " + b);
|
|
749
|
+
const result = a % b;
|
|
750
|
+
return result >= _0n2 ? result : b + result;
|
|
751
|
+
}
|
|
752
|
+
function pow2(x, power, modulo) {
|
|
753
|
+
if (power < _0n2)
|
|
754
|
+
throw new Error("pow2: expected non-negative exponent, got " + power);
|
|
755
|
+
let res = x;
|
|
756
|
+
while (power-- > _0n2) {
|
|
757
|
+
res *= res;
|
|
758
|
+
res %= modulo;
|
|
759
|
+
}
|
|
760
|
+
return res;
|
|
761
|
+
}
|
|
762
|
+
function invert(number, modulo) {
|
|
763
|
+
if (number === _0n2)
|
|
764
|
+
throw new Error("invert: expected non-zero number");
|
|
765
|
+
if (modulo <= _0n2)
|
|
766
|
+
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
767
|
+
let a = mod(number, modulo);
|
|
768
|
+
let b = modulo;
|
|
769
|
+
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
770
|
+
while (a !== _0n2) {
|
|
771
|
+
const q = b / a;
|
|
772
|
+
const r = b - a * q;
|
|
773
|
+
const m = x - u * q;
|
|
774
|
+
const n = y - v * q;
|
|
775
|
+
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
776
|
+
}
|
|
777
|
+
const gcd = b;
|
|
778
|
+
if (gcd !== _1n2)
|
|
779
|
+
throw new Error("invert: does not exist");
|
|
780
|
+
return mod(x, modulo);
|
|
781
|
+
}
|
|
782
|
+
function assertIsSquare(Fp2, root, n) {
|
|
783
|
+
const F = Fp2;
|
|
784
|
+
if (!F.eql(F.sqr(root), n))
|
|
785
|
+
throw new Error("Cannot find square root");
|
|
786
|
+
}
|
|
787
|
+
function sqrt3mod4(Fp2, n) {
|
|
788
|
+
const F = Fp2;
|
|
789
|
+
const p1div4 = (F.ORDER + _1n2) / _4n;
|
|
790
|
+
const root = F.pow(n, p1div4);
|
|
791
|
+
assertIsSquare(F, root, n);
|
|
792
|
+
return root;
|
|
793
|
+
}
|
|
794
|
+
function sqrt5mod8(Fp2, n) {
|
|
795
|
+
const F = Fp2;
|
|
796
|
+
const p5div8 = (F.ORDER - _5n) / _8n;
|
|
797
|
+
const n2 = F.mul(n, _2n);
|
|
798
|
+
const v = F.pow(n2, p5div8);
|
|
799
|
+
const nv = F.mul(n, v);
|
|
800
|
+
const i = F.mul(F.mul(nv, _2n), v);
|
|
801
|
+
const root = F.mul(nv, F.sub(i, F.ONE));
|
|
802
|
+
assertIsSquare(F, root, n);
|
|
803
|
+
return root;
|
|
804
|
+
}
|
|
805
|
+
function sqrt9mod16(P) {
|
|
806
|
+
const Fp_ = Field(P);
|
|
807
|
+
const tn = tonelliShanks(P);
|
|
808
|
+
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
809
|
+
const c2 = tn(Fp_, c1);
|
|
810
|
+
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
811
|
+
const c4 = (P + _7n) / _16n;
|
|
812
|
+
return ((Fp2, n) => {
|
|
813
|
+
const F = Fp2;
|
|
814
|
+
let tv1 = F.pow(n, c4);
|
|
815
|
+
let tv2 = F.mul(tv1, c1);
|
|
816
|
+
const tv3 = F.mul(tv1, c2);
|
|
817
|
+
const tv4 = F.mul(tv1, c3);
|
|
818
|
+
const e1 = F.eql(F.sqr(tv2), n);
|
|
819
|
+
const e2 = F.eql(F.sqr(tv3), n);
|
|
820
|
+
tv1 = F.cmov(tv1, tv2, e1);
|
|
821
|
+
tv2 = F.cmov(tv4, tv3, e2);
|
|
822
|
+
const e3 = F.eql(F.sqr(tv2), n);
|
|
823
|
+
const root = F.cmov(tv1, tv2, e3);
|
|
824
|
+
assertIsSquare(F, root, n);
|
|
825
|
+
return root;
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
function tonelliShanks(P) {
|
|
829
|
+
if (P < _3n)
|
|
830
|
+
throw new Error("sqrt is not defined for small field");
|
|
831
|
+
let Q = P - _1n2;
|
|
832
|
+
let S = 0;
|
|
833
|
+
while (Q % _2n === _0n2) {
|
|
834
|
+
Q /= _2n;
|
|
835
|
+
S++;
|
|
836
|
+
}
|
|
837
|
+
let Z = _2n;
|
|
838
|
+
const _Fp = Field(P);
|
|
839
|
+
while (FpLegendre(_Fp, Z) === 1) {
|
|
840
|
+
if (Z++ > 1e3)
|
|
841
|
+
throw new Error("Cannot find square root: probably non-prime P");
|
|
842
|
+
}
|
|
843
|
+
if (S === 1)
|
|
844
|
+
return sqrt3mod4;
|
|
845
|
+
let cc = _Fp.pow(Z, Q);
|
|
846
|
+
const Q1div2 = (Q + _1n2) / _2n;
|
|
847
|
+
return function tonelliSlow(Fp2, n) {
|
|
848
|
+
const F = Fp2;
|
|
849
|
+
if (F.is0(n))
|
|
850
|
+
return n;
|
|
851
|
+
if (FpLegendre(F, n) !== 1)
|
|
852
|
+
throw new Error("Cannot find square root");
|
|
853
|
+
let M = S;
|
|
854
|
+
let c = F.mul(F.ONE, cc);
|
|
855
|
+
let t = F.pow(n, Q);
|
|
856
|
+
let R = F.pow(n, Q1div2);
|
|
857
|
+
while (!F.eql(t, F.ONE)) {
|
|
858
|
+
if (F.is0(t))
|
|
859
|
+
return F.ZERO;
|
|
860
|
+
let i = 1;
|
|
861
|
+
let t_tmp = F.sqr(t);
|
|
862
|
+
while (!F.eql(t_tmp, F.ONE)) {
|
|
863
|
+
i++;
|
|
864
|
+
t_tmp = F.sqr(t_tmp);
|
|
865
|
+
if (i === M)
|
|
866
|
+
throw new Error("Cannot find square root");
|
|
867
|
+
}
|
|
868
|
+
const exponent = _1n2 << BigInt(M - i - 1);
|
|
869
|
+
const b = F.pow(c, exponent);
|
|
870
|
+
M = i;
|
|
871
|
+
c = F.sqr(b);
|
|
872
|
+
t = F.mul(t, c);
|
|
873
|
+
R = F.mul(R, b);
|
|
874
|
+
}
|
|
875
|
+
return R;
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
function FpSqrt(P) {
|
|
879
|
+
if (P % _4n === _3n)
|
|
880
|
+
return sqrt3mod4;
|
|
881
|
+
if (P % _8n === _5n)
|
|
882
|
+
return sqrt5mod8;
|
|
883
|
+
if (P % _16n === _9n)
|
|
884
|
+
return sqrt9mod16(P);
|
|
885
|
+
return tonelliShanks(P);
|
|
886
|
+
}
|
|
887
|
+
var isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n2) === _1n2;
|
|
888
|
+
var FIELD_FIELDS = [
|
|
889
|
+
"create",
|
|
890
|
+
"isValid",
|
|
891
|
+
"is0",
|
|
892
|
+
"neg",
|
|
893
|
+
"inv",
|
|
894
|
+
"sqrt",
|
|
895
|
+
"sqr",
|
|
896
|
+
"eql",
|
|
897
|
+
"add",
|
|
898
|
+
"sub",
|
|
899
|
+
"mul",
|
|
900
|
+
"pow",
|
|
901
|
+
"div",
|
|
902
|
+
"addN",
|
|
903
|
+
"subN",
|
|
904
|
+
"mulN",
|
|
905
|
+
"sqrN"
|
|
906
|
+
];
|
|
907
|
+
function validateField(field) {
|
|
908
|
+
const initial = {
|
|
909
|
+
ORDER: "bigint",
|
|
910
|
+
BYTES: "number",
|
|
911
|
+
BITS: "number"
|
|
912
|
+
};
|
|
913
|
+
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
914
|
+
map[val] = "function";
|
|
915
|
+
return map;
|
|
916
|
+
}, initial);
|
|
917
|
+
validateObject(field, opts);
|
|
918
|
+
asafenumber(field.BYTES, "BYTES");
|
|
919
|
+
asafenumber(field.BITS, "BITS");
|
|
920
|
+
if (field.BYTES < 1 || field.BITS < 1)
|
|
921
|
+
throw new Error("invalid field: expected BYTES/BITS > 0");
|
|
922
|
+
if (field.ORDER <= _1n2)
|
|
923
|
+
throw new Error("invalid field: expected ORDER > 1, got " + field.ORDER);
|
|
924
|
+
return field;
|
|
925
|
+
}
|
|
926
|
+
function FpPow(Fp2, num, power) {
|
|
927
|
+
const F = Fp2;
|
|
928
|
+
if (power < _0n2)
|
|
929
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
930
|
+
if (power === _0n2)
|
|
931
|
+
return F.ONE;
|
|
932
|
+
if (power === _1n2)
|
|
933
|
+
return num;
|
|
934
|
+
let p = F.ONE;
|
|
935
|
+
let d = num;
|
|
936
|
+
while (power > _0n2) {
|
|
937
|
+
if (power & _1n2)
|
|
938
|
+
p = F.mul(p, d);
|
|
939
|
+
d = F.sqr(d);
|
|
940
|
+
power >>= _1n2;
|
|
941
|
+
}
|
|
942
|
+
return p;
|
|
943
|
+
}
|
|
944
|
+
function FpInvertBatch(Fp2, nums, passZero = false) {
|
|
945
|
+
const F = Fp2;
|
|
946
|
+
const inverted = new Array(nums.length).fill(passZero ? F.ZERO : void 0);
|
|
947
|
+
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
948
|
+
if (F.is0(num))
|
|
949
|
+
return acc;
|
|
950
|
+
inverted[i] = acc;
|
|
951
|
+
return F.mul(acc, num);
|
|
952
|
+
}, F.ONE);
|
|
953
|
+
const invertedAcc = F.inv(multipliedAcc);
|
|
954
|
+
nums.reduceRight((acc, num, i) => {
|
|
955
|
+
if (F.is0(num))
|
|
956
|
+
return acc;
|
|
957
|
+
inverted[i] = F.mul(acc, inverted[i]);
|
|
958
|
+
return F.mul(acc, num);
|
|
959
|
+
}, invertedAcc);
|
|
960
|
+
return inverted;
|
|
961
|
+
}
|
|
962
|
+
function FpLegendre(Fp2, n) {
|
|
963
|
+
const F = Fp2;
|
|
964
|
+
const p1mod2 = (F.ORDER - _1n2) / _2n;
|
|
965
|
+
const powered = F.pow(n, p1mod2);
|
|
966
|
+
const yes = F.eql(powered, F.ONE);
|
|
967
|
+
const zero = F.eql(powered, F.ZERO);
|
|
968
|
+
const no = F.eql(powered, F.neg(F.ONE));
|
|
969
|
+
if (!yes && !zero && !no)
|
|
970
|
+
throw new Error("invalid Legendre symbol result");
|
|
971
|
+
return yes ? 1 : zero ? 0 : -1;
|
|
972
|
+
}
|
|
973
|
+
function nLength(n, nBitLength) {
|
|
974
|
+
if (nBitLength !== void 0)
|
|
975
|
+
anumber2(nBitLength);
|
|
976
|
+
if (n <= _0n2)
|
|
977
|
+
throw new Error("invalid n length: expected positive n, got " + n);
|
|
978
|
+
if (nBitLength !== void 0 && nBitLength < 1)
|
|
979
|
+
throw new Error("invalid n length: expected positive bit length, got " + nBitLength);
|
|
980
|
+
const bits = bitLen(n);
|
|
981
|
+
if (nBitLength !== void 0 && nBitLength < bits)
|
|
982
|
+
throw new Error(`invalid n length: expected bit length (${bits}) >= n.length (${nBitLength})`);
|
|
983
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : bits;
|
|
984
|
+
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
985
|
+
return { nBitLength: _nBitLength, nByteLength };
|
|
986
|
+
}
|
|
987
|
+
var FIELD_SQRT = /* @__PURE__ */ new WeakMap();
|
|
988
|
+
var _Field = class {
|
|
989
|
+
ORDER;
|
|
990
|
+
BITS;
|
|
991
|
+
BYTES;
|
|
992
|
+
isLE;
|
|
993
|
+
ZERO = _0n2;
|
|
994
|
+
ONE = _1n2;
|
|
995
|
+
_lengths;
|
|
996
|
+
_mod;
|
|
997
|
+
constructor(ORDER, opts = {}) {
|
|
998
|
+
if (ORDER <= _1n2)
|
|
999
|
+
throw new Error("invalid field: expected ORDER > 1, got " + ORDER);
|
|
1000
|
+
let _nbitLength = void 0;
|
|
1001
|
+
this.isLE = false;
|
|
1002
|
+
if (opts != null && typeof opts === "object") {
|
|
1003
|
+
if (typeof opts.BITS === "number")
|
|
1004
|
+
_nbitLength = opts.BITS;
|
|
1005
|
+
if (typeof opts.sqrt === "function")
|
|
1006
|
+
Object.defineProperty(this, "sqrt", { value: opts.sqrt, enumerable: true });
|
|
1007
|
+
if (typeof opts.isLE === "boolean")
|
|
1008
|
+
this.isLE = opts.isLE;
|
|
1009
|
+
if (opts.allowedLengths)
|
|
1010
|
+
this._lengths = Object.freeze(opts.allowedLengths.slice());
|
|
1011
|
+
if (typeof opts.modFromBytes === "boolean")
|
|
1012
|
+
this._mod = opts.modFromBytes;
|
|
1013
|
+
}
|
|
1014
|
+
const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);
|
|
1015
|
+
if (nByteLength > 2048)
|
|
1016
|
+
throw new Error("invalid field: expected ORDER of <= 2048 bytes");
|
|
1017
|
+
this.ORDER = ORDER;
|
|
1018
|
+
this.BITS = nBitLength;
|
|
1019
|
+
this.BYTES = nByteLength;
|
|
1020
|
+
Object.freeze(this);
|
|
1021
|
+
}
|
|
1022
|
+
create(num) {
|
|
1023
|
+
return mod(num, this.ORDER);
|
|
1024
|
+
}
|
|
1025
|
+
isValid(num) {
|
|
1026
|
+
if (typeof num !== "bigint")
|
|
1027
|
+
throw new TypeError("invalid field element: expected bigint, got " + typeof num);
|
|
1028
|
+
return _0n2 <= num && num < this.ORDER;
|
|
1029
|
+
}
|
|
1030
|
+
is0(num) {
|
|
1031
|
+
return num === _0n2;
|
|
1032
|
+
}
|
|
1033
|
+
// is valid and invertible
|
|
1034
|
+
isValidNot0(num) {
|
|
1035
|
+
return !this.is0(num) && this.isValid(num);
|
|
1036
|
+
}
|
|
1037
|
+
isOdd(num) {
|
|
1038
|
+
return (num & _1n2) === _1n2;
|
|
1039
|
+
}
|
|
1040
|
+
neg(num) {
|
|
1041
|
+
return mod(-num, this.ORDER);
|
|
1042
|
+
}
|
|
1043
|
+
eql(lhs, rhs) {
|
|
1044
|
+
return lhs === rhs;
|
|
1045
|
+
}
|
|
1046
|
+
sqr(num) {
|
|
1047
|
+
return mod(num * num, this.ORDER);
|
|
1048
|
+
}
|
|
1049
|
+
add(lhs, rhs) {
|
|
1050
|
+
return mod(lhs + rhs, this.ORDER);
|
|
1051
|
+
}
|
|
1052
|
+
sub(lhs, rhs) {
|
|
1053
|
+
return mod(lhs - rhs, this.ORDER);
|
|
1054
|
+
}
|
|
1055
|
+
mul(lhs, rhs) {
|
|
1056
|
+
return mod(lhs * rhs, this.ORDER);
|
|
1057
|
+
}
|
|
1058
|
+
pow(num, power) {
|
|
1059
|
+
return FpPow(this, num, power);
|
|
1060
|
+
}
|
|
1061
|
+
div(lhs, rhs) {
|
|
1062
|
+
return mod(lhs * invert(rhs, this.ORDER), this.ORDER);
|
|
1063
|
+
}
|
|
1064
|
+
// Same as above, but doesn't normalize
|
|
1065
|
+
sqrN(num) {
|
|
1066
|
+
return num * num;
|
|
1067
|
+
}
|
|
1068
|
+
addN(lhs, rhs) {
|
|
1069
|
+
return lhs + rhs;
|
|
1070
|
+
}
|
|
1071
|
+
subN(lhs, rhs) {
|
|
1072
|
+
return lhs - rhs;
|
|
1073
|
+
}
|
|
1074
|
+
mulN(lhs, rhs) {
|
|
1075
|
+
return lhs * rhs;
|
|
1076
|
+
}
|
|
1077
|
+
inv(num) {
|
|
1078
|
+
return invert(num, this.ORDER);
|
|
1079
|
+
}
|
|
1080
|
+
sqrt(num) {
|
|
1081
|
+
let sqrt = FIELD_SQRT.get(this);
|
|
1082
|
+
if (!sqrt)
|
|
1083
|
+
FIELD_SQRT.set(this, sqrt = FpSqrt(this.ORDER));
|
|
1084
|
+
return sqrt(this, num);
|
|
1085
|
+
}
|
|
1086
|
+
toBytes(num) {
|
|
1087
|
+
return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
|
|
1088
|
+
}
|
|
1089
|
+
fromBytes(bytes, skipValidation = false) {
|
|
1090
|
+
abytes2(bytes);
|
|
1091
|
+
const { _lengths: allowedLengths, BYTES, isLE: isLE3, ORDER, _mod: modFromBytes } = this;
|
|
1092
|
+
if (allowedLengths) {
|
|
1093
|
+
if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
1094
|
+
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
1095
|
+
}
|
|
1096
|
+
const padded = new Uint8Array(BYTES);
|
|
1097
|
+
padded.set(bytes, isLE3 ? 0 : padded.length - bytes.length);
|
|
1098
|
+
bytes = padded;
|
|
1099
|
+
}
|
|
1100
|
+
if (bytes.length !== BYTES)
|
|
1101
|
+
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
1102
|
+
let scalar = isLE3 ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
1103
|
+
if (modFromBytes)
|
|
1104
|
+
scalar = mod(scalar, ORDER);
|
|
1105
|
+
if (!skipValidation) {
|
|
1106
|
+
if (!this.isValid(scalar))
|
|
1107
|
+
throw new Error("invalid field element: outside of range 0..ORDER");
|
|
1108
|
+
}
|
|
1109
|
+
return scalar;
|
|
1110
|
+
}
|
|
1111
|
+
// TODO: we don't need it here, move out to separate fn
|
|
1112
|
+
invertBatch(lst) {
|
|
1113
|
+
return FpInvertBatch(this, lst);
|
|
1114
|
+
}
|
|
1115
|
+
// We can't move this out because Fp6, Fp12 implement it
|
|
1116
|
+
// and it's unclear what to return in there.
|
|
1117
|
+
cmov(a, b, condition) {
|
|
1118
|
+
abool(condition, "condition");
|
|
1119
|
+
return condition ? b : a;
|
|
1120
|
+
}
|
|
1121
|
+
};
|
|
1122
|
+
Object.freeze(_Field.prototype);
|
|
1123
|
+
function Field(ORDER, opts = {}) {
|
|
1124
|
+
return new _Field(ORDER, opts);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// ../../node_modules/@noble/curves/abstract/curve.js
|
|
1128
|
+
var _0n3 = /* @__PURE__ */ BigInt(0);
|
|
1129
|
+
var _1n3 = /* @__PURE__ */ BigInt(1);
|
|
1130
|
+
function negateCt(condition, item) {
|
|
1131
|
+
const neg = item.negate();
|
|
1132
|
+
return condition ? neg : item;
|
|
1133
|
+
}
|
|
1134
|
+
function normalizeZ(c, points) {
|
|
1135
|
+
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
1136
|
+
return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
|
|
1137
|
+
}
|
|
1138
|
+
function validateW(W, bits) {
|
|
1139
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
|
1140
|
+
throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W);
|
|
1141
|
+
}
|
|
1142
|
+
function calcWOpts(W, scalarBits) {
|
|
1143
|
+
validateW(W, scalarBits);
|
|
1144
|
+
const windows = Math.ceil(scalarBits / W) + 1;
|
|
1145
|
+
const windowSize = 2 ** (W - 1);
|
|
1146
|
+
const maxNumber = 2 ** W;
|
|
1147
|
+
const mask = bitMask(W);
|
|
1148
|
+
const shiftBy = BigInt(W);
|
|
1149
|
+
return { windows, windowSize, mask, maxNumber, shiftBy };
|
|
1150
|
+
}
|
|
1151
|
+
function calcOffsets(n, window, wOpts) {
|
|
1152
|
+
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
|
1153
|
+
let wbits = Number(n & mask);
|
|
1154
|
+
let nextN = n >> shiftBy;
|
|
1155
|
+
if (wbits > windowSize) {
|
|
1156
|
+
wbits -= maxNumber;
|
|
1157
|
+
nextN += _1n3;
|
|
1158
|
+
}
|
|
1159
|
+
const offsetStart = window * windowSize;
|
|
1160
|
+
const offset = offsetStart + Math.abs(wbits) - 1;
|
|
1161
|
+
const isZero = wbits === 0;
|
|
1162
|
+
const isNeg = wbits < 0;
|
|
1163
|
+
const isNegF = window % 2 !== 0;
|
|
1164
|
+
const offsetF = offsetStart;
|
|
1165
|
+
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
|
1166
|
+
}
|
|
1167
|
+
var pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
1168
|
+
var pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
1169
|
+
function getW(P) {
|
|
1170
|
+
return pointWindowSizes.get(P) || 1;
|
|
1171
|
+
}
|
|
1172
|
+
function assert0(n) {
|
|
1173
|
+
if (n !== _0n3)
|
|
1174
|
+
throw new Error("invalid wNAF");
|
|
1175
|
+
}
|
|
1176
|
+
var wNAF = class {
|
|
1177
|
+
BASE;
|
|
1178
|
+
ZERO;
|
|
1179
|
+
Fn;
|
|
1180
|
+
bits;
|
|
1181
|
+
// Parametrized with a given Point class (not individual point)
|
|
1182
|
+
constructor(Point, bits) {
|
|
1183
|
+
this.BASE = Point.BASE;
|
|
1184
|
+
this.ZERO = Point.ZERO;
|
|
1185
|
+
this.Fn = Point.Fn;
|
|
1186
|
+
this.bits = bits;
|
|
1187
|
+
}
|
|
1188
|
+
// non-const time multiplication ladder
|
|
1189
|
+
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
1190
|
+
let d = elm;
|
|
1191
|
+
while (n > _0n3) {
|
|
1192
|
+
if (n & _1n3)
|
|
1193
|
+
p = p.add(d);
|
|
1194
|
+
d = d.double();
|
|
1195
|
+
n >>= _1n3;
|
|
1196
|
+
}
|
|
1197
|
+
return p;
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
1201
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
1202
|
+
* Number of precomputed points depends on the curve size:
|
|
1203
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
1204
|
+
* - 𝑊 is the window size
|
|
1205
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
1206
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
1207
|
+
* @param point - Point instance
|
|
1208
|
+
* @param W - window size
|
|
1209
|
+
* @returns precomputed point tables flattened to a single array
|
|
1210
|
+
*/
|
|
1211
|
+
precomputeWindow(point, W) {
|
|
1212
|
+
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
1213
|
+
const points = [];
|
|
1214
|
+
let p = point;
|
|
1215
|
+
let base = p;
|
|
1216
|
+
for (let window = 0; window < windows; window++) {
|
|
1217
|
+
base = p;
|
|
1218
|
+
points.push(base);
|
|
1219
|
+
for (let i = 1; i < windowSize; i++) {
|
|
1220
|
+
base = base.add(p);
|
|
1221
|
+
points.push(base);
|
|
1222
|
+
}
|
|
1223
|
+
p = base.double();
|
|
1224
|
+
}
|
|
1225
|
+
return points;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
1229
|
+
* More compact implementation:
|
|
1230
|
+
* https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
|
1231
|
+
* @returns real and fake (for const-time) points
|
|
1232
|
+
*/
|
|
1233
|
+
wNAF(W, precomputes, n) {
|
|
1234
|
+
if (!this.Fn.isValid(n))
|
|
1235
|
+
throw new Error("invalid scalar");
|
|
1236
|
+
let p = this.ZERO;
|
|
1237
|
+
let f = this.BASE;
|
|
1238
|
+
const wo = calcWOpts(W, this.bits);
|
|
1239
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
1240
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
|
1241
|
+
n = nextN;
|
|
1242
|
+
if (isZero) {
|
|
1243
|
+
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
1244
|
+
} else {
|
|
1245
|
+
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
assert0(n);
|
|
1249
|
+
return { p, f };
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Implements unsafe EC multiplication using precomputed tables
|
|
1253
|
+
* and w-ary non-adjacent form.
|
|
1254
|
+
* @param acc - accumulator point to add result of multiplication
|
|
1255
|
+
* @returns point
|
|
1256
|
+
*/
|
|
1257
|
+
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
1258
|
+
const wo = calcWOpts(W, this.bits);
|
|
1259
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
1260
|
+
if (n === _0n3)
|
|
1261
|
+
break;
|
|
1262
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
1263
|
+
n = nextN;
|
|
1264
|
+
if (isZero) {
|
|
1265
|
+
continue;
|
|
1266
|
+
} else {
|
|
1267
|
+
const item = precomputes[offset];
|
|
1268
|
+
acc = acc.add(isNeg ? item.negate() : item);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
assert0(n);
|
|
1272
|
+
return acc;
|
|
1273
|
+
}
|
|
1274
|
+
getPrecomputes(W, point, transform) {
|
|
1275
|
+
let comp = pointPrecomputes.get(point);
|
|
1276
|
+
if (!comp) {
|
|
1277
|
+
comp = this.precomputeWindow(point, W);
|
|
1278
|
+
if (W !== 1) {
|
|
1279
|
+
if (typeof transform === "function")
|
|
1280
|
+
comp = transform(comp);
|
|
1281
|
+
pointPrecomputes.set(point, comp);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
return comp;
|
|
1285
|
+
}
|
|
1286
|
+
cached(point, scalar, transform) {
|
|
1287
|
+
const W = getW(point);
|
|
1288
|
+
return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
|
|
1289
|
+
}
|
|
1290
|
+
unsafe(point, scalar, transform, prev) {
|
|
1291
|
+
const W = getW(point);
|
|
1292
|
+
if (W === 1)
|
|
1293
|
+
return this._unsafeLadder(point, scalar, prev);
|
|
1294
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
|
|
1295
|
+
}
|
|
1296
|
+
// We calculate precomputes for elliptic curve point multiplication
|
|
1297
|
+
// using windowed method. This specifies window size and
|
|
1298
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
|
1299
|
+
createCache(P, W) {
|
|
1300
|
+
validateW(W, this.bits);
|
|
1301
|
+
pointWindowSizes.set(P, W);
|
|
1302
|
+
pointPrecomputes.delete(P);
|
|
1303
|
+
}
|
|
1304
|
+
hasCache(elm) {
|
|
1305
|
+
return getW(elm) !== 1;
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
function createField(order, field, isLE3) {
|
|
1309
|
+
if (field) {
|
|
1310
|
+
if (field.ORDER !== order)
|
|
1311
|
+
throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
|
|
1312
|
+
validateField(field);
|
|
1313
|
+
return field;
|
|
1314
|
+
} else {
|
|
1315
|
+
return Field(order, { isLE: isLE3 });
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
1319
|
+
if (FpFnLE === void 0)
|
|
1320
|
+
FpFnLE = type === "edwards";
|
|
1321
|
+
if (!CURVE || typeof CURVE !== "object")
|
|
1322
|
+
throw new Error(`expected valid ${type} CURVE object`);
|
|
1323
|
+
for (const p of ["p", "n", "h"]) {
|
|
1324
|
+
const val = CURVE[p];
|
|
1325
|
+
if (!(typeof val === "bigint" && val > _0n3))
|
|
1326
|
+
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
1327
|
+
}
|
|
1328
|
+
const Fp2 = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
1329
|
+
const Fn2 = createField(CURVE.n, curveOpts.Fn, FpFnLE);
|
|
1330
|
+
const _b = type === "weierstrass" ? "b" : "d";
|
|
1331
|
+
const params = ["Gx", "Gy", "a", _b];
|
|
1332
|
+
for (const p of params) {
|
|
1333
|
+
if (!Fp2.isValid(CURVE[p]))
|
|
1334
|
+
throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
|
|
1335
|
+
}
|
|
1336
|
+
CURVE = Object.freeze(Object.assign({}, CURVE));
|
|
1337
|
+
return { CURVE, Fp: Fp2, Fn: Fn2 };
|
|
1338
|
+
}
|
|
1339
|
+
function createKeygen(randomSecretKey, getPublicKey) {
|
|
1340
|
+
return function keygen(seed) {
|
|
1341
|
+
const secretKey = randomSecretKey(seed);
|
|
1342
|
+
return { secretKey, publicKey: getPublicKey(secretKey) };
|
|
1343
|
+
};
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
// ../../node_modules/@noble/curves/abstract/edwards.js
|
|
1347
|
+
var _0n4 = /* @__PURE__ */ BigInt(0);
|
|
1348
|
+
var _1n4 = /* @__PURE__ */ BigInt(1);
|
|
1349
|
+
var _2n2 = /* @__PURE__ */ BigInt(2);
|
|
1350
|
+
var _8n2 = /* @__PURE__ */ BigInt(8);
|
|
1351
|
+
function isEdValidXY(Fp2, CURVE, x, y) {
|
|
1352
|
+
const x2 = Fp2.sqr(x);
|
|
1353
|
+
const y2 = Fp2.sqr(y);
|
|
1354
|
+
const left = Fp2.add(Fp2.mul(CURVE.a, x2), y2);
|
|
1355
|
+
const right = Fp2.add(Fp2.ONE, Fp2.mul(CURVE.d, Fp2.mul(x2, y2)));
|
|
1356
|
+
return Fp2.eql(left, right);
|
|
1357
|
+
}
|
|
1358
|
+
function edwards(params, extraOpts = {}) {
|
|
1359
|
+
const opts = extraOpts;
|
|
1360
|
+
const validated = createCurveFields("edwards", params, opts, opts.FpFnLE);
|
|
1361
|
+
const { Fp: Fp2, Fn: Fn2 } = validated;
|
|
1362
|
+
let CURVE = validated.CURVE;
|
|
1363
|
+
const { h: cofactor } = CURVE;
|
|
1364
|
+
validateObject(opts, {}, { uvRatio: "function" });
|
|
1365
|
+
const MASK = _2n2 << BigInt(Fn2.BYTES * 8) - _1n4;
|
|
1366
|
+
const modP = (n) => Fp2.create(n);
|
|
1367
|
+
const uvRatio2 = opts.uvRatio === void 0 ? (u, v) => {
|
|
1368
|
+
try {
|
|
1369
|
+
return { isValid: true, value: Fp2.sqrt(Fp2.div(u, v)) };
|
|
1370
|
+
} catch (e) {
|
|
1371
|
+
return { isValid: false, value: _0n4 };
|
|
1372
|
+
}
|
|
1373
|
+
} : opts.uvRatio;
|
|
1374
|
+
if (!isEdValidXY(Fp2, CURVE, CURVE.Gx, CURVE.Gy))
|
|
1375
|
+
throw new Error("bad curve params: generator point");
|
|
1376
|
+
function acoord(title, n, banZero = false) {
|
|
1377
|
+
const min = banZero ? _1n4 : _0n4;
|
|
1378
|
+
aInRange("coordinate " + title, n, min, MASK);
|
|
1379
|
+
return n;
|
|
1380
|
+
}
|
|
1381
|
+
function aedpoint(other) {
|
|
1382
|
+
if (!(other instanceof Point))
|
|
1383
|
+
throw new Error("EdwardsPoint expected");
|
|
1384
|
+
}
|
|
1385
|
+
class Point {
|
|
1386
|
+
// base / generator point
|
|
1387
|
+
static BASE = new Point(CURVE.Gx, CURVE.Gy, _1n4, modP(CURVE.Gx * CURVE.Gy));
|
|
1388
|
+
// zero / infinity / identity point
|
|
1389
|
+
static ZERO = new Point(_0n4, _1n4, _1n4, _0n4);
|
|
1390
|
+
// 0, 1, 1, 0
|
|
1391
|
+
// math field
|
|
1392
|
+
static Fp = Fp2;
|
|
1393
|
+
// scalar field
|
|
1394
|
+
static Fn = Fn2;
|
|
1395
|
+
X;
|
|
1396
|
+
Y;
|
|
1397
|
+
Z;
|
|
1398
|
+
T;
|
|
1399
|
+
constructor(X, Y, Z, T) {
|
|
1400
|
+
this.X = acoord("x", X);
|
|
1401
|
+
this.Y = acoord("y", Y);
|
|
1402
|
+
this.Z = acoord("z", Z, true);
|
|
1403
|
+
this.T = acoord("t", T);
|
|
1404
|
+
Object.freeze(this);
|
|
1405
|
+
}
|
|
1406
|
+
static CURVE() {
|
|
1407
|
+
return CURVE;
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Create one extended Edwards point from affine coordinates.
|
|
1411
|
+
* Does NOT validate that the point is on-curve or torsion-free.
|
|
1412
|
+
* Use `.assertValidity()` on adversarial inputs.
|
|
1413
|
+
*/
|
|
1414
|
+
static fromAffine(p) {
|
|
1415
|
+
if (p instanceof Point)
|
|
1416
|
+
throw new Error("extended point not allowed");
|
|
1417
|
+
const { x, y } = p || {};
|
|
1418
|
+
acoord("x", x);
|
|
1419
|
+
acoord("y", y);
|
|
1420
|
+
return new Point(x, y, _1n4, modP(x * y));
|
|
1421
|
+
}
|
|
1422
|
+
// Uses algo from RFC8032 5.1.3.
|
|
1423
|
+
static fromBytes(bytes, zip215 = false) {
|
|
1424
|
+
const len = Fp2.BYTES;
|
|
1425
|
+
const { a, d } = CURVE;
|
|
1426
|
+
bytes = copyBytes(abytes2(bytes, len, "point"));
|
|
1427
|
+
abool(zip215, "zip215");
|
|
1428
|
+
const normed = copyBytes(bytes);
|
|
1429
|
+
const lastByte = bytes[len - 1];
|
|
1430
|
+
normed[len - 1] = lastByte & ~128;
|
|
1431
|
+
const y = bytesToNumberLE(normed);
|
|
1432
|
+
const max = zip215 ? MASK : Fp2.ORDER;
|
|
1433
|
+
aInRange("point.y", y, _0n4, max);
|
|
1434
|
+
const y2 = modP(y * y);
|
|
1435
|
+
const u = modP(y2 - _1n4);
|
|
1436
|
+
const v = modP(d * y2 - a);
|
|
1437
|
+
let { isValid, value: x } = uvRatio2(u, v);
|
|
1438
|
+
if (!isValid)
|
|
1439
|
+
throw new Error("bad point: invalid y coordinate");
|
|
1440
|
+
const isXOdd = (x & _1n4) === _1n4;
|
|
1441
|
+
const isLastByteOdd = (lastByte & 128) !== 0;
|
|
1442
|
+
if (!zip215 && x === _0n4 && isLastByteOdd)
|
|
1443
|
+
throw new Error("bad point: x=0 and x_0=1");
|
|
1444
|
+
if (isLastByteOdd !== isXOdd)
|
|
1445
|
+
x = modP(-x);
|
|
1446
|
+
return Point.fromAffine({ x, y });
|
|
1447
|
+
}
|
|
1448
|
+
static fromHex(hex, zip215 = false) {
|
|
1449
|
+
return Point.fromBytes(hexToBytes2(hex), zip215);
|
|
1450
|
+
}
|
|
1451
|
+
get x() {
|
|
1452
|
+
return this.toAffine().x;
|
|
1453
|
+
}
|
|
1454
|
+
get y() {
|
|
1455
|
+
return this.toAffine().y;
|
|
1456
|
+
}
|
|
1457
|
+
precompute(windowSize = 8, isLazy = true) {
|
|
1458
|
+
wnaf.createCache(this, windowSize);
|
|
1459
|
+
if (!isLazy)
|
|
1460
|
+
this.multiply(_2n2);
|
|
1461
|
+
return this;
|
|
1462
|
+
}
|
|
1463
|
+
// Useful in fromAffine() - not for fromBytes(), which always created valid points.
|
|
1464
|
+
assertValidity() {
|
|
1465
|
+
const p = this;
|
|
1466
|
+
const { a, d } = CURVE;
|
|
1467
|
+
if (p.is0())
|
|
1468
|
+
throw new Error("bad point: ZERO");
|
|
1469
|
+
const { X, Y, Z, T } = p;
|
|
1470
|
+
const X2 = modP(X * X);
|
|
1471
|
+
const Y2 = modP(Y * Y);
|
|
1472
|
+
const Z2 = modP(Z * Z);
|
|
1473
|
+
const Z4 = modP(Z2 * Z2);
|
|
1474
|
+
const aX2 = modP(X2 * a);
|
|
1475
|
+
const left = modP(Z2 * modP(aX2 + Y2));
|
|
1476
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2)));
|
|
1477
|
+
if (left !== right)
|
|
1478
|
+
throw new Error("bad point: equation left != right (1)");
|
|
1479
|
+
const XY = modP(X * Y);
|
|
1480
|
+
const ZT = modP(Z * T);
|
|
1481
|
+
if (XY !== ZT)
|
|
1482
|
+
throw new Error("bad point: equation left != right (2)");
|
|
1483
|
+
}
|
|
1484
|
+
// Compare one point to another.
|
|
1485
|
+
equals(other) {
|
|
1486
|
+
aedpoint(other);
|
|
1487
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1488
|
+
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
1489
|
+
const X1Z2 = modP(X1 * Z2);
|
|
1490
|
+
const X2Z1 = modP(X2 * Z1);
|
|
1491
|
+
const Y1Z2 = modP(Y1 * Z2);
|
|
1492
|
+
const Y2Z1 = modP(Y2 * Z1);
|
|
1493
|
+
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
1494
|
+
}
|
|
1495
|
+
is0() {
|
|
1496
|
+
return this.equals(Point.ZERO);
|
|
1497
|
+
}
|
|
1498
|
+
negate() {
|
|
1499
|
+
return new Point(modP(-this.X), this.Y, this.Z, modP(-this.T));
|
|
1500
|
+
}
|
|
1501
|
+
// Fast algo for doubling Extended Point.
|
|
1502
|
+
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
|
|
1503
|
+
// Cost: 4M + 4S + 1*a + 6add + 1*2.
|
|
1504
|
+
double() {
|
|
1505
|
+
const { a } = CURVE;
|
|
1506
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1507
|
+
const A = modP(X1 * X1);
|
|
1508
|
+
const B = modP(Y1 * Y1);
|
|
1509
|
+
const C = modP(_2n2 * modP(Z1 * Z1));
|
|
1510
|
+
const D = modP(a * A);
|
|
1511
|
+
const x1y1 = X1 + Y1;
|
|
1512
|
+
const E = modP(modP(x1y1 * x1y1) - A - B);
|
|
1513
|
+
const G = D + B;
|
|
1514
|
+
const F = G - C;
|
|
1515
|
+
const H = D - B;
|
|
1516
|
+
const X3 = modP(E * F);
|
|
1517
|
+
const Y3 = modP(G * H);
|
|
1518
|
+
const T3 = modP(E * H);
|
|
1519
|
+
const Z3 = modP(F * G);
|
|
1520
|
+
return new Point(X3, Y3, Z3, T3);
|
|
1521
|
+
}
|
|
1522
|
+
// Fast algo for adding 2 Extended Points.
|
|
1523
|
+
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
|
1524
|
+
// Cost: 9M + 1*a + 1*d + 7add.
|
|
1525
|
+
add(other) {
|
|
1526
|
+
aedpoint(other);
|
|
1527
|
+
const { a, d } = CURVE;
|
|
1528
|
+
const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
|
|
1529
|
+
const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
|
|
1530
|
+
const A = modP(X1 * X2);
|
|
1531
|
+
const B = modP(Y1 * Y2);
|
|
1532
|
+
const C = modP(T1 * d * T2);
|
|
1533
|
+
const D = modP(Z1 * Z2);
|
|
1534
|
+
const E = modP((X1 + Y1) * (X2 + Y2) - A - B);
|
|
1535
|
+
const F = D - C;
|
|
1536
|
+
const G = D + C;
|
|
1537
|
+
const H = modP(B - a * A);
|
|
1538
|
+
const X3 = modP(E * F);
|
|
1539
|
+
const Y3 = modP(G * H);
|
|
1540
|
+
const T3 = modP(E * H);
|
|
1541
|
+
const Z3 = modP(F * G);
|
|
1542
|
+
return new Point(X3, Y3, Z3, T3);
|
|
1543
|
+
}
|
|
1544
|
+
subtract(other) {
|
|
1545
|
+
aedpoint(other);
|
|
1546
|
+
return this.add(other.negate());
|
|
1547
|
+
}
|
|
1548
|
+
// Constant-time multiplication.
|
|
1549
|
+
multiply(scalar) {
|
|
1550
|
+
if (!Fn2.isValidNot0(scalar))
|
|
1551
|
+
throw new RangeError("invalid scalar: expected 1 <= sc < curve.n");
|
|
1552
|
+
const { p, f } = wnaf.cached(this, scalar, (p2) => normalizeZ(Point, p2));
|
|
1553
|
+
return normalizeZ(Point, [p, f])[0];
|
|
1554
|
+
}
|
|
1555
|
+
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
1556
|
+
// It's faster, but should only be used when you don't care about
|
|
1557
|
+
// an exposed private key e.g. sig verification.
|
|
1558
|
+
// Keeps the same subgroup-scalar contract: 0 is allowed for public-scalar callers, but
|
|
1559
|
+
// n and larger values are rejected instead of being reduced mod n to the identity point.
|
|
1560
|
+
multiplyUnsafe(scalar) {
|
|
1561
|
+
if (!Fn2.isValid(scalar))
|
|
1562
|
+
throw new RangeError("invalid scalar: expected 0 <= sc < curve.n");
|
|
1563
|
+
if (scalar === _0n4)
|
|
1564
|
+
return Point.ZERO;
|
|
1565
|
+
if (this.is0() || scalar === _1n4)
|
|
1566
|
+
return this;
|
|
1567
|
+
return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p));
|
|
1568
|
+
}
|
|
1569
|
+
// Checks if point is of small order.
|
|
1570
|
+
// If you add something to small order point, you will have "dirty"
|
|
1571
|
+
// point with torsion component.
|
|
1572
|
+
// Clears cofactor and checks if the result is 0.
|
|
1573
|
+
isSmallOrder() {
|
|
1574
|
+
return this.clearCofactor().is0();
|
|
1575
|
+
}
|
|
1576
|
+
// Multiplies point by curve order and checks if the result is 0.
|
|
1577
|
+
// Returns `false` is the point is dirty.
|
|
1578
|
+
isTorsionFree() {
|
|
1579
|
+
return wnaf.unsafe(this, CURVE.n).is0();
|
|
1580
|
+
}
|
|
1581
|
+
// Converts Extended point to default (x, y) coordinates.
|
|
1582
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
1583
|
+
toAffine(invertedZ) {
|
|
1584
|
+
const p = this;
|
|
1585
|
+
let iz = invertedZ;
|
|
1586
|
+
const { X, Y, Z } = p;
|
|
1587
|
+
const is0 = p.is0();
|
|
1588
|
+
if (iz == null)
|
|
1589
|
+
iz = is0 ? _8n2 : Fp2.inv(Z);
|
|
1590
|
+
const x = modP(X * iz);
|
|
1591
|
+
const y = modP(Y * iz);
|
|
1592
|
+
const zz = Fp2.mul(Z, iz);
|
|
1593
|
+
if (is0)
|
|
1594
|
+
return { x: _0n4, y: _1n4 };
|
|
1595
|
+
if (zz !== _1n4)
|
|
1596
|
+
throw new Error("invZ was invalid");
|
|
1597
|
+
return { x, y };
|
|
1598
|
+
}
|
|
1599
|
+
clearCofactor() {
|
|
1600
|
+
if (cofactor === _1n4)
|
|
1601
|
+
return this;
|
|
1602
|
+
return this.multiplyUnsafe(cofactor);
|
|
1603
|
+
}
|
|
1604
|
+
toBytes() {
|
|
1605
|
+
const { x, y } = this.toAffine();
|
|
1606
|
+
const bytes = Fp2.toBytes(y);
|
|
1607
|
+
bytes[bytes.length - 1] |= x & _1n4 ? 128 : 0;
|
|
1608
|
+
return bytes;
|
|
1609
|
+
}
|
|
1610
|
+
toHex() {
|
|
1611
|
+
return bytesToHex2(this.toBytes());
|
|
1612
|
+
}
|
|
1613
|
+
toString() {
|
|
1614
|
+
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
const wnaf = new wNAF(Point, Fn2.BITS);
|
|
1618
|
+
if (Fn2.BITS >= 8)
|
|
1619
|
+
Point.BASE.precompute(8);
|
|
1620
|
+
Object.freeze(Point.prototype);
|
|
1621
|
+
Object.freeze(Point);
|
|
1622
|
+
return Point;
|
|
1623
|
+
}
|
|
1624
|
+
var PrimeEdwardsPoint = class {
|
|
1625
|
+
static BASE;
|
|
1626
|
+
static ZERO;
|
|
1627
|
+
static Fp;
|
|
1628
|
+
static Fn;
|
|
1629
|
+
ep;
|
|
1630
|
+
/**
|
|
1631
|
+
* Wrap one internal Edwards representative directly.
|
|
1632
|
+
* This is not a canonical encoding boundary: alternate Edwards
|
|
1633
|
+
* representatives may still describe the same abstract wrapper element.
|
|
1634
|
+
*/
|
|
1635
|
+
constructor(ep) {
|
|
1636
|
+
this.ep = ep;
|
|
1637
|
+
}
|
|
1638
|
+
// Static methods that must be implemented by subclasses
|
|
1639
|
+
static fromBytes(_bytes) {
|
|
1640
|
+
notImplemented();
|
|
1641
|
+
}
|
|
1642
|
+
static fromHex(_hex) {
|
|
1643
|
+
notImplemented();
|
|
1644
|
+
}
|
|
1645
|
+
get x() {
|
|
1646
|
+
return this.toAffine().x;
|
|
1647
|
+
}
|
|
1648
|
+
get y() {
|
|
1649
|
+
return this.toAffine().y;
|
|
1650
|
+
}
|
|
1651
|
+
// Common implementations
|
|
1652
|
+
clearCofactor() {
|
|
1653
|
+
return this;
|
|
1654
|
+
}
|
|
1655
|
+
assertValidity() {
|
|
1656
|
+
this.ep.assertValidity();
|
|
1657
|
+
}
|
|
1658
|
+
/**
|
|
1659
|
+
* Return affine coordinates of the current internal Edwards representative.
|
|
1660
|
+
* This is a convenience helper, not a canonical Ristretto/Decaf encoding.
|
|
1661
|
+
* Equal abstract elements may expose different `x` / `y`; use
|
|
1662
|
+
* `toBytes()` / `fromBytes()` for canonical roundtrips.
|
|
1663
|
+
*/
|
|
1664
|
+
toAffine(invertedZ) {
|
|
1665
|
+
return this.ep.toAffine(invertedZ);
|
|
1666
|
+
}
|
|
1667
|
+
toHex() {
|
|
1668
|
+
return bytesToHex2(this.toBytes());
|
|
1669
|
+
}
|
|
1670
|
+
toString() {
|
|
1671
|
+
return this.toHex();
|
|
1672
|
+
}
|
|
1673
|
+
isTorsionFree() {
|
|
1674
|
+
return true;
|
|
1675
|
+
}
|
|
1676
|
+
isSmallOrder() {
|
|
1677
|
+
return false;
|
|
1678
|
+
}
|
|
1679
|
+
add(other) {
|
|
1680
|
+
this.assertSame(other);
|
|
1681
|
+
return this.init(this.ep.add(other.ep));
|
|
1682
|
+
}
|
|
1683
|
+
subtract(other) {
|
|
1684
|
+
this.assertSame(other);
|
|
1685
|
+
return this.init(this.ep.subtract(other.ep));
|
|
1686
|
+
}
|
|
1687
|
+
multiply(scalar) {
|
|
1688
|
+
return this.init(this.ep.multiply(scalar));
|
|
1689
|
+
}
|
|
1690
|
+
multiplyUnsafe(scalar) {
|
|
1691
|
+
return this.init(this.ep.multiplyUnsafe(scalar));
|
|
1692
|
+
}
|
|
1693
|
+
double() {
|
|
1694
|
+
return this.init(this.ep.double());
|
|
1695
|
+
}
|
|
1696
|
+
negate() {
|
|
1697
|
+
return this.init(this.ep.negate());
|
|
1698
|
+
}
|
|
1699
|
+
precompute(windowSize, isLazy) {
|
|
1700
|
+
this.ep.precompute(windowSize, isLazy);
|
|
1701
|
+
return this;
|
|
1702
|
+
}
|
|
1703
|
+
};
|
|
1704
|
+
function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
1705
|
+
if (typeof cHash !== "function")
|
|
1706
|
+
throw new Error('"hash" function param is required');
|
|
1707
|
+
const hash = cHash;
|
|
1708
|
+
const opts = eddsaOpts;
|
|
1709
|
+
validateObject(opts, {}, {
|
|
1710
|
+
adjustScalarBytes: "function",
|
|
1711
|
+
randomBytes: "function",
|
|
1712
|
+
domain: "function",
|
|
1713
|
+
prehash: "function",
|
|
1714
|
+
zip215: "boolean",
|
|
1715
|
+
mapToCurve: "function"
|
|
1716
|
+
});
|
|
1717
|
+
const { prehash } = opts;
|
|
1718
|
+
const { BASE, Fp: Fp2, Fn: Fn2 } = Point;
|
|
1719
|
+
const outputLen = hash.outputLen;
|
|
1720
|
+
const expectedLen = 2 * Fp2.BYTES;
|
|
1721
|
+
if (outputLen !== void 0) {
|
|
1722
|
+
asafenumber(outputLen, "hash.outputLen");
|
|
1723
|
+
if (outputLen !== expectedLen)
|
|
1724
|
+
throw new Error(`hash.outputLen must be ${expectedLen}, got ${outputLen}`);
|
|
1725
|
+
}
|
|
1726
|
+
const randomBytes5 = opts.randomBytes === void 0 ? randomBytes2 : opts.randomBytes;
|
|
1727
|
+
const adjustScalarBytes2 = opts.adjustScalarBytes === void 0 ? (bytes) => bytes : opts.adjustScalarBytes;
|
|
1728
|
+
const domain = opts.domain === void 0 ? (data, ctx, phflag) => {
|
|
1729
|
+
abool(phflag, "phflag");
|
|
1730
|
+
if (ctx.length || phflag)
|
|
1731
|
+
throw new Error("Contexts/pre-hash are not supported");
|
|
1732
|
+
return data;
|
|
1733
|
+
} : opts.domain;
|
|
1734
|
+
function modN_LE(hash2) {
|
|
1735
|
+
return Fn2.create(bytesToNumberLE(hash2));
|
|
1736
|
+
}
|
|
1737
|
+
function getPrivateScalar(key) {
|
|
1738
|
+
const len = lengths.secretKey;
|
|
1739
|
+
abytes2(key, lengths.secretKey, "secretKey");
|
|
1740
|
+
const hashed = abytes2(hash(key), 2 * len, "hashedSecretKey");
|
|
1741
|
+
const head = adjustScalarBytes2(hashed.slice(0, len));
|
|
1742
|
+
const prefix = hashed.slice(len, 2 * len);
|
|
1743
|
+
const scalar = modN_LE(head);
|
|
1744
|
+
return { head, prefix, scalar };
|
|
1745
|
+
}
|
|
1746
|
+
function getExtendedPublicKey(secretKey) {
|
|
1747
|
+
const { head, prefix, scalar } = getPrivateScalar(secretKey);
|
|
1748
|
+
const point = BASE.multiply(scalar);
|
|
1749
|
+
const pointBytes = point.toBytes();
|
|
1750
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
1751
|
+
}
|
|
1752
|
+
function getPublicKey(secretKey) {
|
|
1753
|
+
return getExtendedPublicKey(secretKey).pointBytes;
|
|
1754
|
+
}
|
|
1755
|
+
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
|
1756
|
+
const msg = concatBytes2(...msgs);
|
|
1757
|
+
return modN_LE(hash(domain(msg, abytes2(context, void 0, "context"), !!prehash)));
|
|
1758
|
+
}
|
|
1759
|
+
function sign(msg, secretKey, options = {}) {
|
|
1760
|
+
msg = abytes2(msg, void 0, "message");
|
|
1761
|
+
if (prehash)
|
|
1762
|
+
msg = prehash(msg);
|
|
1763
|
+
const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
|
|
1764
|
+
const r = hashDomainToScalar(options.context, prefix, msg);
|
|
1765
|
+
const R = BASE.multiply(r).toBytes();
|
|
1766
|
+
const k = hashDomainToScalar(options.context, R, pointBytes, msg);
|
|
1767
|
+
const s = Fn2.create(r + k * scalar);
|
|
1768
|
+
if (!Fn2.isValid(s))
|
|
1769
|
+
throw new Error("sign failed: invalid s");
|
|
1770
|
+
const rs = concatBytes2(R, Fn2.toBytes(s));
|
|
1771
|
+
return abytes2(rs, lengths.signature, "result");
|
|
1772
|
+
}
|
|
1773
|
+
const verifyOpts = {
|
|
1774
|
+
zip215: opts.zip215
|
|
1775
|
+
};
|
|
1776
|
+
function verify(sig, msg, publicKey, options = verifyOpts) {
|
|
1777
|
+
const { context } = options;
|
|
1778
|
+
const zip215 = options.zip215 === void 0 ? !!verifyOpts.zip215 : options.zip215;
|
|
1779
|
+
const len = lengths.signature;
|
|
1780
|
+
sig = abytes2(sig, len, "signature");
|
|
1781
|
+
msg = abytes2(msg, void 0, "message");
|
|
1782
|
+
publicKey = abytes2(publicKey, lengths.publicKey, "publicKey");
|
|
1783
|
+
if (zip215 !== void 0)
|
|
1784
|
+
abool(zip215, "zip215");
|
|
1785
|
+
if (prehash)
|
|
1786
|
+
msg = prehash(msg);
|
|
1787
|
+
const mid = len / 2;
|
|
1788
|
+
const r = sig.subarray(0, mid);
|
|
1789
|
+
const s = bytesToNumberLE(sig.subarray(mid, len));
|
|
1790
|
+
let A, R, SB;
|
|
1791
|
+
try {
|
|
1792
|
+
A = Point.fromBytes(publicKey, zip215);
|
|
1793
|
+
R = Point.fromBytes(r, zip215);
|
|
1794
|
+
SB = BASE.multiplyUnsafe(s);
|
|
1795
|
+
} catch (error) {
|
|
1796
|
+
return false;
|
|
1797
|
+
}
|
|
1798
|
+
if (!zip215 && A.isSmallOrder())
|
|
1799
|
+
return false;
|
|
1800
|
+
const k = hashDomainToScalar(context, r, publicKey, msg);
|
|
1801
|
+
const RkA = R.add(A.multiplyUnsafe(k));
|
|
1802
|
+
return RkA.subtract(SB).clearCofactor().is0();
|
|
1803
|
+
}
|
|
1804
|
+
const _size = Fp2.BYTES;
|
|
1805
|
+
const lengths = {
|
|
1806
|
+
secretKey: _size,
|
|
1807
|
+
publicKey: _size,
|
|
1808
|
+
signature: 2 * _size,
|
|
1809
|
+
seed: _size
|
|
1810
|
+
};
|
|
1811
|
+
function randomSecretKey(seed) {
|
|
1812
|
+
seed = seed === void 0 ? randomBytes5(lengths.seed) : seed;
|
|
1813
|
+
return abytes2(seed, lengths.seed, "seed");
|
|
1814
|
+
}
|
|
1815
|
+
function isValidSecretKey(key) {
|
|
1816
|
+
return isBytes2(key) && key.length === lengths.secretKey;
|
|
1817
|
+
}
|
|
1818
|
+
function isValidPublicKey(key, zip215) {
|
|
1819
|
+
try {
|
|
1820
|
+
return !!Point.fromBytes(key, zip215 === void 0 ? verifyOpts.zip215 : zip215);
|
|
1821
|
+
} catch (error) {
|
|
1822
|
+
return false;
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
const utils = {
|
|
1826
|
+
getExtendedPublicKey,
|
|
1827
|
+
randomSecretKey,
|
|
1828
|
+
isValidSecretKey,
|
|
1829
|
+
isValidPublicKey,
|
|
1830
|
+
/**
|
|
1831
|
+
* Converts ed public key to x public key. Uses formula:
|
|
1832
|
+
* - ed25519:
|
|
1833
|
+
* - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
|
1834
|
+
* - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
|
1835
|
+
* - ed448:
|
|
1836
|
+
* - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
|
1837
|
+
* - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
|
1838
|
+
*/
|
|
1839
|
+
toMontgomery(publicKey) {
|
|
1840
|
+
const { y } = Point.fromBytes(publicKey);
|
|
1841
|
+
const size = lengths.publicKey;
|
|
1842
|
+
const is25519 = size === 32;
|
|
1843
|
+
if (!is25519 && size !== 57)
|
|
1844
|
+
throw new Error("only defined for 25519 and 448");
|
|
1845
|
+
const u = is25519 ? Fp2.div(_1n4 + y, _1n4 - y) : Fp2.div(y - _1n4, y + _1n4);
|
|
1846
|
+
return Fp2.toBytes(u);
|
|
1847
|
+
},
|
|
1848
|
+
toMontgomerySecret(secretKey) {
|
|
1849
|
+
const size = lengths.secretKey;
|
|
1850
|
+
abytes2(secretKey, size);
|
|
1851
|
+
const hashed = hash(secretKey.subarray(0, size));
|
|
1852
|
+
return adjustScalarBytes2(hashed).subarray(0, size);
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
Object.freeze(lengths);
|
|
1856
|
+
Object.freeze(utils);
|
|
1857
|
+
return Object.freeze({
|
|
1858
|
+
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
1859
|
+
getPublicKey,
|
|
1860
|
+
sign,
|
|
1861
|
+
verify,
|
|
1862
|
+
utils,
|
|
1863
|
+
Point,
|
|
1864
|
+
lengths
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
// ../../node_modules/@noble/curves/abstract/hash-to-curve.js
|
|
1869
|
+
function i2osp(value, length) {
|
|
1870
|
+
asafenumber(value);
|
|
1871
|
+
asafenumber(length);
|
|
1872
|
+
if (length < 0 || length > 4)
|
|
1873
|
+
throw new Error("invalid I2OSP length: " + length);
|
|
1874
|
+
if (value < 0 || value > 2 ** (8 * length) - 1)
|
|
1875
|
+
throw new Error("invalid I2OSP input: " + value);
|
|
1876
|
+
const res = Array.from({ length }).fill(0);
|
|
1877
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
1878
|
+
res[i] = value & 255;
|
|
1879
|
+
value >>>= 8;
|
|
1880
|
+
}
|
|
1881
|
+
return new Uint8Array(res);
|
|
1882
|
+
}
|
|
1883
|
+
function strxor(a, b) {
|
|
1884
|
+
const arr = new Uint8Array(a.length);
|
|
1885
|
+
for (let i = 0; i < a.length; i++) {
|
|
1886
|
+
arr[i] = a[i] ^ b[i];
|
|
1887
|
+
}
|
|
1888
|
+
return arr;
|
|
1889
|
+
}
|
|
1890
|
+
function normDST(DST) {
|
|
1891
|
+
if (!isBytes2(DST) && typeof DST !== "string")
|
|
1892
|
+
throw new Error("DST must be Uint8Array or ascii string");
|
|
1893
|
+
const dst = typeof DST === "string" ? asciiToBytes(DST) : DST;
|
|
1894
|
+
if (dst.length === 0)
|
|
1895
|
+
throw new Error("DST must be non-empty");
|
|
1896
|
+
return dst;
|
|
1897
|
+
}
|
|
1898
|
+
function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
1899
|
+
abytes2(msg);
|
|
1900
|
+
asafenumber(lenInBytes);
|
|
1901
|
+
DST = normDST(DST);
|
|
1902
|
+
if (DST.length > 255)
|
|
1903
|
+
DST = H(concatBytes2(asciiToBytes("H2C-OVERSIZE-DST-"), DST));
|
|
1904
|
+
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
|
1905
|
+
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
|
1906
|
+
if (lenInBytes > 65535 || ell > 255)
|
|
1907
|
+
throw new Error("expand_message_xmd: invalid lenInBytes");
|
|
1908
|
+
const DST_prime = concatBytes2(DST, i2osp(DST.length, 1));
|
|
1909
|
+
const Z_pad = new Uint8Array(r_in_bytes);
|
|
1910
|
+
const l_i_b_str = i2osp(lenInBytes, 2);
|
|
1911
|
+
const b = new Array(ell);
|
|
1912
|
+
const b_0 = H(concatBytes2(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
|
1913
|
+
b[0] = H(concatBytes2(b_0, i2osp(1, 1), DST_prime));
|
|
1914
|
+
for (let i = 1; i < ell; i++) {
|
|
1915
|
+
const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime];
|
|
1916
|
+
b[i] = H(concatBytes2(...args));
|
|
1917
|
+
}
|
|
1918
|
+
const pseudo_random_bytes = concatBytes2(...b);
|
|
1919
|
+
return pseudo_random_bytes.slice(0, lenInBytes);
|
|
1920
|
+
}
|
|
1921
|
+
var _DST_scalar = "HashToScalar-";
|
|
1922
|
+
|
|
1923
|
+
// ../../node_modules/@noble/curves/abstract/montgomery.js
|
|
1924
|
+
var _0n5 = BigInt(0);
|
|
1925
|
+
var _1n5 = BigInt(1);
|
|
1926
|
+
var _2n3 = BigInt(2);
|
|
1927
|
+
function validateOpts(curve) {
|
|
1928
|
+
validateObject(curve, {
|
|
1929
|
+
P: "bigint",
|
|
1930
|
+
type: "string",
|
|
1931
|
+
adjustScalarBytes: "function",
|
|
1932
|
+
powPminus2: "function"
|
|
1933
|
+
}, {
|
|
1934
|
+
randomBytes: "function"
|
|
1935
|
+
});
|
|
1936
|
+
return Object.freeze({ ...curve });
|
|
1937
|
+
}
|
|
1938
|
+
function montgomery(curveDef) {
|
|
1939
|
+
const CURVE = validateOpts(curveDef);
|
|
1940
|
+
const { P, type, adjustScalarBytes: adjustScalarBytes2, powPminus2, randomBytes: rand } = CURVE;
|
|
1941
|
+
const is25519 = type === "x25519";
|
|
1942
|
+
if (!is25519 && type !== "x448")
|
|
1943
|
+
throw new Error("invalid type");
|
|
1944
|
+
const randomBytes_ = rand === void 0 ? randomBytes2 : rand;
|
|
1945
|
+
const montgomeryBits = is25519 ? 255 : 448;
|
|
1946
|
+
const fieldLen = is25519 ? 32 : 56;
|
|
1947
|
+
const Gu = is25519 ? BigInt(9) : BigInt(5);
|
|
1948
|
+
const a24 = is25519 ? BigInt(121665) : BigInt(39081);
|
|
1949
|
+
const minScalar = is25519 ? _2n3 ** BigInt(254) : _2n3 ** BigInt(447);
|
|
1950
|
+
const maxAdded = is25519 ? BigInt(8) * _2n3 ** BigInt(251) - _1n5 : BigInt(4) * _2n3 ** BigInt(445) - _1n5;
|
|
1951
|
+
const maxScalar = minScalar + maxAdded + _1n5;
|
|
1952
|
+
const modP = (n) => mod(n, P);
|
|
1953
|
+
const GuBytes = encodeU(Gu);
|
|
1954
|
+
function encodeU(u) {
|
|
1955
|
+
return numberToBytesLE(modP(u), fieldLen);
|
|
1956
|
+
}
|
|
1957
|
+
function decodeU(u) {
|
|
1958
|
+
const _u = copyBytes(abytes2(u, fieldLen, "uCoordinate"));
|
|
1959
|
+
if (is25519)
|
|
1960
|
+
_u[31] &= 127;
|
|
1961
|
+
return modP(bytesToNumberLE(_u));
|
|
1962
|
+
}
|
|
1963
|
+
function decodeScalar(scalar) {
|
|
1964
|
+
return bytesToNumberLE(adjustScalarBytes2(copyBytes(abytes2(scalar, fieldLen, "scalar"))));
|
|
1965
|
+
}
|
|
1966
|
+
function scalarMult(scalar, u) {
|
|
1967
|
+
const pu = montgomeryLadder(decodeU(u), decodeScalar(scalar));
|
|
1968
|
+
if (pu === _0n5)
|
|
1969
|
+
throw new Error("invalid private or public key received");
|
|
1970
|
+
return encodeU(pu);
|
|
1971
|
+
}
|
|
1972
|
+
function scalarMultBase(scalar) {
|
|
1973
|
+
return scalarMult(scalar, GuBytes);
|
|
1974
|
+
}
|
|
1975
|
+
const getPublicKey = scalarMultBase;
|
|
1976
|
+
const getSharedSecret = scalarMult;
|
|
1977
|
+
function cswap(swap, x_2, x_3) {
|
|
1978
|
+
const dummy = modP(swap * (x_2 - x_3));
|
|
1979
|
+
x_2 = modP(x_2 - dummy);
|
|
1980
|
+
x_3 = modP(x_3 + dummy);
|
|
1981
|
+
return { x_2, x_3 };
|
|
1982
|
+
}
|
|
1983
|
+
function montgomeryLadder(u, scalar) {
|
|
1984
|
+
aInRange("u", u, _0n5, P);
|
|
1985
|
+
aInRange("scalar", scalar, minScalar, maxScalar);
|
|
1986
|
+
const k = scalar;
|
|
1987
|
+
const x_1 = u;
|
|
1988
|
+
let x_2 = _1n5;
|
|
1989
|
+
let z_2 = _0n5;
|
|
1990
|
+
let x_3 = u;
|
|
1991
|
+
let z_3 = _1n5;
|
|
1992
|
+
let swap = _0n5;
|
|
1993
|
+
for (let t = BigInt(montgomeryBits - 1); t >= _0n5; t--) {
|
|
1994
|
+
const k_t = k >> t & _1n5;
|
|
1995
|
+
swap ^= k_t;
|
|
1996
|
+
({ x_2, x_3 } = cswap(swap, x_2, x_3));
|
|
1997
|
+
({ x_2: z_2, x_3: z_3 } = cswap(swap, z_2, z_3));
|
|
1998
|
+
swap = k_t;
|
|
1999
|
+
const A = x_2 + z_2;
|
|
2000
|
+
const AA = modP(A * A);
|
|
2001
|
+
const B = x_2 - z_2;
|
|
2002
|
+
const BB = modP(B * B);
|
|
2003
|
+
const E = AA - BB;
|
|
2004
|
+
const C = x_3 + z_3;
|
|
2005
|
+
const D = x_3 - z_3;
|
|
2006
|
+
const DA = modP(D * A);
|
|
2007
|
+
const CB = modP(C * B);
|
|
2008
|
+
const dacb = DA + CB;
|
|
2009
|
+
const da_cb = DA - CB;
|
|
2010
|
+
x_3 = modP(dacb * dacb);
|
|
2011
|
+
z_3 = modP(x_1 * modP(da_cb * da_cb));
|
|
2012
|
+
x_2 = modP(AA * BB);
|
|
2013
|
+
z_2 = modP(E * (AA + modP(a24 * E)));
|
|
2014
|
+
}
|
|
2015
|
+
({ x_2, x_3 } = cswap(swap, x_2, x_3));
|
|
2016
|
+
({ x_2: z_2, x_3: z_3 } = cswap(swap, z_2, z_3));
|
|
2017
|
+
const z2 = powPminus2(z_2);
|
|
2018
|
+
return modP(x_2 * z2);
|
|
2019
|
+
}
|
|
2020
|
+
const lengths = {
|
|
2021
|
+
secretKey: fieldLen,
|
|
2022
|
+
publicKey: fieldLen,
|
|
2023
|
+
seed: fieldLen
|
|
2024
|
+
};
|
|
2025
|
+
const randomSecretKey = (seed) => {
|
|
2026
|
+
seed = seed === void 0 ? randomBytes_(fieldLen) : seed;
|
|
2027
|
+
abytes2(seed, lengths.seed, "seed");
|
|
2028
|
+
return seed;
|
|
2029
|
+
};
|
|
2030
|
+
const utils = { randomSecretKey };
|
|
2031
|
+
Object.freeze(lengths);
|
|
2032
|
+
Object.freeze(utils);
|
|
2033
|
+
return Object.freeze({
|
|
2034
|
+
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
2035
|
+
getSharedSecret,
|
|
2036
|
+
getPublicKey,
|
|
2037
|
+
scalarMult,
|
|
2038
|
+
scalarMultBase,
|
|
2039
|
+
utils,
|
|
2040
|
+
GuBytes: GuBytes.slice(),
|
|
2041
|
+
lengths
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// ../../node_modules/@noble/curves/ed25519.js
|
|
2046
|
+
var _0n6 = /* @__PURE__ */ BigInt(0);
|
|
2047
|
+
var _1n6 = /* @__PURE__ */ BigInt(1);
|
|
2048
|
+
var _2n4 = /* @__PURE__ */ BigInt(2);
|
|
2049
|
+
var _3n2 = /* @__PURE__ */ BigInt(3);
|
|
2050
|
+
var _5n2 = /* @__PURE__ */ BigInt(5);
|
|
2051
|
+
var _8n3 = /* @__PURE__ */ BigInt(8);
|
|
2052
|
+
var ed25519_CURVE_p = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
2053
|
+
var ed25519_CURVE = /* @__PURE__ */ (() => ({
|
|
2054
|
+
p: ed25519_CURVE_p,
|
|
2055
|
+
n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
|
|
2056
|
+
h: _8n3,
|
|
2057
|
+
a: BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
|
|
2058
|
+
d: BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),
|
|
2059
|
+
Gx: BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),
|
|
2060
|
+
Gy: BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")
|
|
2061
|
+
}))();
|
|
2062
|
+
function ed25519_pow_2_252_3(x) {
|
|
2063
|
+
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
|
2064
|
+
const P = ed25519_CURVE_p;
|
|
2065
|
+
const x2 = x * x % P;
|
|
2066
|
+
const b2 = x2 * x % P;
|
|
2067
|
+
const b4 = pow2(b2, _2n4, P) * b2 % P;
|
|
2068
|
+
const b5 = pow2(b4, _1n6, P) * x % P;
|
|
2069
|
+
const b10 = pow2(b5, _5n2, P) * b5 % P;
|
|
2070
|
+
const b20 = pow2(b10, _10n, P) * b10 % P;
|
|
2071
|
+
const b40 = pow2(b20, _20n, P) * b20 % P;
|
|
2072
|
+
const b80 = pow2(b40, _40n, P) * b40 % P;
|
|
2073
|
+
const b160 = pow2(b80, _80n, P) * b80 % P;
|
|
2074
|
+
const b240 = pow2(b160, _80n, P) * b80 % P;
|
|
2075
|
+
const b250 = pow2(b240, _10n, P) * b10 % P;
|
|
2076
|
+
const pow_p_5_8 = pow2(b250, _2n4, P) * x % P;
|
|
2077
|
+
return { pow_p_5_8, b2 };
|
|
2078
|
+
}
|
|
2079
|
+
function adjustScalarBytes(bytes) {
|
|
2080
|
+
bytes[0] &= 248;
|
|
2081
|
+
bytes[31] &= 127;
|
|
2082
|
+
bytes[31] |= 64;
|
|
2083
|
+
return bytes;
|
|
2084
|
+
}
|
|
2085
|
+
var ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
2086
|
+
function uvRatio(u, v) {
|
|
2087
|
+
const P = ed25519_CURVE_p;
|
|
2088
|
+
const v3 = mod(v * v * v, P);
|
|
2089
|
+
const v7 = mod(v3 * v3 * v, P);
|
|
2090
|
+
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
2091
|
+
let x = mod(u * v3 * pow, P);
|
|
2092
|
+
const vx2 = mod(v * x * x, P);
|
|
2093
|
+
const root1 = x;
|
|
2094
|
+
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
2095
|
+
const useRoot1 = vx2 === u;
|
|
2096
|
+
const useRoot2 = vx2 === mod(-u, P);
|
|
2097
|
+
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P);
|
|
2098
|
+
if (useRoot1)
|
|
2099
|
+
x = root1;
|
|
2100
|
+
if (useRoot2 || noRoot)
|
|
2101
|
+
x = root2;
|
|
2102
|
+
if (isNegativeLE(x, P))
|
|
2103
|
+
x = mod(-x, P);
|
|
2104
|
+
return { isValid: useRoot1 || useRoot2, value: x };
|
|
2105
|
+
}
|
|
2106
|
+
var ed25519_Point = /* @__PURE__ */ edwards(ed25519_CURVE, { uvRatio });
|
|
2107
|
+
var Fp = /* @__PURE__ */ (() => ed25519_Point.Fp)();
|
|
2108
|
+
var Fn = /* @__PURE__ */ (() => ed25519_Point.Fn)();
|
|
2109
|
+
function ed(opts) {
|
|
2110
|
+
return eddsa(ed25519_Point, sha512, Object.assign({ adjustScalarBytes, zip215: true }, opts));
|
|
2111
|
+
}
|
|
2112
|
+
var ed25519 = /* @__PURE__ */ ed({});
|
|
2113
|
+
var x25519 = /* @__PURE__ */ (() => {
|
|
2114
|
+
const P = ed25519_CURVE_p;
|
|
2115
|
+
return montgomery({
|
|
2116
|
+
P,
|
|
2117
|
+
type: "x25519",
|
|
2118
|
+
powPminus2: (x) => {
|
|
2119
|
+
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
|
|
2120
|
+
return mod(pow2(pow_p_5_8, _3n2, P) * b2, P);
|
|
2121
|
+
},
|
|
2122
|
+
adjustScalarBytes
|
|
2123
|
+
});
|
|
2124
|
+
})();
|
|
2125
|
+
var SQRT_M1 = ED25519_SQRT_M1;
|
|
2126
|
+
var SQRT_AD_MINUS_ONE = /* @__PURE__ */ BigInt("25063068953384623474111414158702152701244531502492656460079210482610430750235");
|
|
2127
|
+
var INVSQRT_A_MINUS_D = /* @__PURE__ */ BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578");
|
|
2128
|
+
var ONE_MINUS_D_SQ = /* @__PURE__ */ BigInt("1159843021668779879193775521855586647937357759715417654439879720876111806838");
|
|
2129
|
+
var D_MINUS_ONE_SQ = /* @__PURE__ */ BigInt("40440834346308536858101042469323190826248399146238708352240133220865137265952");
|
|
2130
|
+
var invertSqrt = (number) => uvRatio(_1n6, number);
|
|
2131
|
+
var MAX_255B = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
2132
|
+
var bytes255ToNumberLE = (bytes) => Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
|
2133
|
+
function calcElligatorRistrettoMap(r0) {
|
|
2134
|
+
const { d } = ed25519_CURVE;
|
|
2135
|
+
const P = ed25519_CURVE_p;
|
|
2136
|
+
const mod2 = (n) => Fp.create(n);
|
|
2137
|
+
const r = mod2(SQRT_M1 * r0 * r0);
|
|
2138
|
+
const Ns = mod2((r + _1n6) * ONE_MINUS_D_SQ);
|
|
2139
|
+
let c = BigInt(-1);
|
|
2140
|
+
const D = mod2((c - d * r) * mod2(r + d));
|
|
2141
|
+
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
2142
|
+
let s_ = mod2(s * r0);
|
|
2143
|
+
if (!isNegativeLE(s_, P))
|
|
2144
|
+
s_ = mod2(-s_);
|
|
2145
|
+
if (!Ns_D_is_sq)
|
|
2146
|
+
s = s_;
|
|
2147
|
+
if (!Ns_D_is_sq)
|
|
2148
|
+
c = r;
|
|
2149
|
+
const Nt = mod2(c * (r - _1n6) * D_MINUS_ONE_SQ - D);
|
|
2150
|
+
const s2 = s * s;
|
|
2151
|
+
const W0 = mod2((s + s) * D);
|
|
2152
|
+
const W1 = mod2(Nt * SQRT_AD_MINUS_ONE);
|
|
2153
|
+
const W2 = mod2(_1n6 - s2);
|
|
2154
|
+
const W3 = mod2(_1n6 + s2);
|
|
2155
|
+
return new ed25519_Point(mod2(W0 * W3), mod2(W2 * W1), mod2(W1 * W3), mod2(W0 * W2));
|
|
2156
|
+
}
|
|
2157
|
+
var _RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
2158
|
+
// Do NOT change syntax: the following gymnastics is done,
|
|
2159
|
+
// because typescript strips comments, which makes bundlers disable tree-shaking.
|
|
2160
|
+
// prettier-ignore
|
|
2161
|
+
static BASE = /* @__PURE__ */ (() => new __RistrettoPoint(ed25519_Point.BASE))();
|
|
2162
|
+
// prettier-ignore
|
|
2163
|
+
static ZERO = /* @__PURE__ */ (() => new __RistrettoPoint(ed25519_Point.ZERO))();
|
|
2164
|
+
// prettier-ignore
|
|
2165
|
+
static Fp = /* @__PURE__ */ (() => Fp)();
|
|
2166
|
+
// prettier-ignore
|
|
2167
|
+
static Fn = /* @__PURE__ */ (() => Fn)();
|
|
2168
|
+
constructor(ep) {
|
|
2169
|
+
super(ep);
|
|
2170
|
+
}
|
|
2171
|
+
/**
|
|
2172
|
+
* Create one Ristretto255 point from affine Edwards coordinates.
|
|
2173
|
+
* This wraps the internal Edwards representative directly and is not a
|
|
2174
|
+
* canonical ristretto255 decoding path.
|
|
2175
|
+
* Use `toBytes()` / `fromBytes()` if canonical ristretto255 bytes matter.
|
|
2176
|
+
*/
|
|
2177
|
+
static fromAffine(ap) {
|
|
2178
|
+
return new __RistrettoPoint(ed25519_Point.fromAffine(ap));
|
|
2179
|
+
}
|
|
2180
|
+
assertSame(other) {
|
|
2181
|
+
if (!(other instanceof __RistrettoPoint))
|
|
2182
|
+
throw new Error("RistrettoPoint expected");
|
|
2183
|
+
}
|
|
2184
|
+
init(ep) {
|
|
2185
|
+
return new __RistrettoPoint(ep);
|
|
2186
|
+
}
|
|
2187
|
+
static fromBytes(bytes) {
|
|
2188
|
+
abytes(bytes, 32);
|
|
2189
|
+
const { a, d } = ed25519_CURVE;
|
|
2190
|
+
const P = ed25519_CURVE_p;
|
|
2191
|
+
const mod2 = (n) => Fp.create(n);
|
|
2192
|
+
const s = bytes255ToNumberLE(bytes);
|
|
2193
|
+
if (!equalBytes(Fp.toBytes(s), bytes) || isNegativeLE(s, P))
|
|
2194
|
+
throw new Error("invalid ristretto255 encoding 1");
|
|
2195
|
+
const s2 = mod2(s * s);
|
|
2196
|
+
const u1 = mod2(_1n6 + a * s2);
|
|
2197
|
+
const u2 = mod2(_1n6 - a * s2);
|
|
2198
|
+
const u1_2 = mod2(u1 * u1);
|
|
2199
|
+
const u2_2 = mod2(u2 * u2);
|
|
2200
|
+
const v = mod2(a * d * u1_2 - u2_2);
|
|
2201
|
+
const { isValid, value: I } = invertSqrt(mod2(v * u2_2));
|
|
2202
|
+
const Dx = mod2(I * u2);
|
|
2203
|
+
const Dy = mod2(I * Dx * v);
|
|
2204
|
+
let x = mod2((s + s) * Dx);
|
|
2205
|
+
if (isNegativeLE(x, P))
|
|
2206
|
+
x = mod2(-x);
|
|
2207
|
+
const y = mod2(u1 * Dy);
|
|
2208
|
+
const t = mod2(x * y);
|
|
2209
|
+
if (!isValid || isNegativeLE(t, P) || y === _0n6)
|
|
2210
|
+
throw new Error("invalid ristretto255 encoding 2");
|
|
2211
|
+
return new __RistrettoPoint(new ed25519_Point(x, y, _1n6, t));
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Converts ristretto-encoded string to ristretto point.
|
|
2215
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
|
|
2216
|
+
* @param hex - Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
2217
|
+
*/
|
|
2218
|
+
static fromHex(hex) {
|
|
2219
|
+
return __RistrettoPoint.fromBytes(hexToBytes(hex));
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Encodes ristretto point to Uint8Array.
|
|
2223
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).
|
|
2224
|
+
*/
|
|
2225
|
+
toBytes() {
|
|
2226
|
+
let { X, Y, Z, T } = this.ep;
|
|
2227
|
+
const P = ed25519_CURVE_p;
|
|
2228
|
+
const mod2 = (n) => Fp.create(n);
|
|
2229
|
+
const u1 = mod2(mod2(Z + Y) * mod2(Z - Y));
|
|
2230
|
+
const u2 = mod2(X * Y);
|
|
2231
|
+
const u2sq = mod2(u2 * u2);
|
|
2232
|
+
const { value: invsqrt } = invertSqrt(mod2(u1 * u2sq));
|
|
2233
|
+
const D1 = mod2(invsqrt * u1);
|
|
2234
|
+
const D2 = mod2(invsqrt * u2);
|
|
2235
|
+
const zInv = mod2(D1 * D2 * T);
|
|
2236
|
+
let D;
|
|
2237
|
+
if (isNegativeLE(T * zInv, P)) {
|
|
2238
|
+
let _x = mod2(Y * SQRT_M1);
|
|
2239
|
+
let _y = mod2(X * SQRT_M1);
|
|
2240
|
+
X = _x;
|
|
2241
|
+
Y = _y;
|
|
2242
|
+
D = mod2(D1 * INVSQRT_A_MINUS_D);
|
|
2243
|
+
} else {
|
|
2244
|
+
D = D2;
|
|
2245
|
+
}
|
|
2246
|
+
if (isNegativeLE(X * zInv, P))
|
|
2247
|
+
Y = mod2(-Y);
|
|
2248
|
+
let s = mod2((Z - Y) * D);
|
|
2249
|
+
if (isNegativeLE(s, P))
|
|
2250
|
+
s = mod2(-s);
|
|
2251
|
+
return Fp.toBytes(s);
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Compares two Ristretto points.
|
|
2255
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals).
|
|
2256
|
+
*/
|
|
2257
|
+
equals(other) {
|
|
2258
|
+
this.assertSame(other);
|
|
2259
|
+
const { X: X1, Y: Y1 } = this.ep;
|
|
2260
|
+
const { X: X2, Y: Y2 } = other.ep;
|
|
2261
|
+
const mod2 = (n) => Fp.create(n);
|
|
2262
|
+
const one = mod2(X1 * Y2) === mod2(Y1 * X2);
|
|
2263
|
+
const two = mod2(Y1 * Y2) === mod2(X1 * X2);
|
|
2264
|
+
return one || two;
|
|
2265
|
+
}
|
|
2266
|
+
is0() {
|
|
2267
|
+
return this.equals(__RistrettoPoint.ZERO);
|
|
2268
|
+
}
|
|
2269
|
+
};
|
|
2270
|
+
Object.freeze(_RistrettoPoint.BASE);
|
|
2271
|
+
Object.freeze(_RistrettoPoint.ZERO);
|
|
2272
|
+
Object.freeze(_RistrettoPoint.prototype);
|
|
2273
|
+
Object.freeze(_RistrettoPoint);
|
|
2274
|
+
var ristretto255_hasher = Object.freeze({
|
|
2275
|
+
Point: _RistrettoPoint,
|
|
2276
|
+
/**
|
|
2277
|
+
* Spec: https://www.rfc-editor.org/rfc/rfc9380.html#name-hashing-to-ristretto255. Caveats:
|
|
2278
|
+
* * There are no test vectors
|
|
2279
|
+
* * encodeToCurve / mapToCurve is undefined
|
|
2280
|
+
* * mapToCurve would be `calcElligatorRistrettoMap(scalars[0])`, not ristretto255_map!
|
|
2281
|
+
* * hashToScalar is undefined too, so we just use OPRF implementation
|
|
2282
|
+
* * We cannot re-use 'createHasher', because ristretto255_map is different algorithm/RFC
|
|
2283
|
+
(os2ip -> bytes255ToNumberLE)
|
|
2284
|
+
* * mapToCurve == calcElligatorRistrettoMap, hashToCurve == ristretto255_map
|
|
2285
|
+
* * hashToScalar is undefined in RFC9380 for ristretto, so we use the OPRF
|
|
2286
|
+
version here. Using `bytes255ToNumblerLE` will create a different result
|
|
2287
|
+
if we use `bytes255ToNumberLE` as os2ip
|
|
2288
|
+
* * current version is closest to spec.
|
|
2289
|
+
*/
|
|
2290
|
+
hashToCurve(msg, options) {
|
|
2291
|
+
const DST = options?.DST === void 0 ? "ristretto255_XMD:SHA-512_R255MAP_RO_" : options.DST;
|
|
2292
|
+
const xmd = expand_message_xmd(msg, DST, 64, sha512);
|
|
2293
|
+
return ristretto255_hasher.deriveToCurve(xmd);
|
|
2294
|
+
},
|
|
2295
|
+
hashToScalar(msg, options = { DST: _DST_scalar }) {
|
|
2296
|
+
const xmd = expand_message_xmd(msg, options.DST, 64, sha512);
|
|
2297
|
+
return Fn.create(bytesToNumberLE(xmd));
|
|
2298
|
+
},
|
|
2299
|
+
/**
|
|
2300
|
+
* HashToCurve-like construction based on RFC 9496 (Element Derivation).
|
|
2301
|
+
* Converts 64 uniform random bytes into a curve point.
|
|
2302
|
+
*
|
|
2303
|
+
* WARNING: This represents an older hash-to-curve construction from before
|
|
2304
|
+
* RFC 9380 was finalized.
|
|
2305
|
+
* It was later reused as a component in the newer
|
|
2306
|
+
* `hash_to_ristretto255` function defined in RFC 9380.
|
|
2307
|
+
*/
|
|
2308
|
+
deriveToCurve(bytes) {
|
|
2309
|
+
abytes(bytes, 64);
|
|
2310
|
+
const r1 = bytes255ToNumberLE(bytes.subarray(0, 32));
|
|
2311
|
+
const R1 = calcElligatorRistrettoMap(r1);
|
|
2312
|
+
const r2 = bytes255ToNumberLE(bytes.subarray(32, 64));
|
|
2313
|
+
const R2 = calcElligatorRistrettoMap(r2);
|
|
2314
|
+
return new _RistrettoPoint(R1.add(R2));
|
|
2315
|
+
}
|
|
2316
|
+
});
|
|
2317
|
+
|
|
2318
|
+
// ../../node_modules/@noble/hashes/_blake.js
|
|
2319
|
+
var BSIGMA = /* @__PURE__ */ Uint8Array.from([
|
|
2320
|
+
0,
|
|
2321
|
+
1,
|
|
2322
|
+
2,
|
|
2323
|
+
3,
|
|
2324
|
+
4,
|
|
2325
|
+
5,
|
|
2326
|
+
6,
|
|
2327
|
+
7,
|
|
2328
|
+
8,
|
|
2329
|
+
9,
|
|
2330
|
+
10,
|
|
2331
|
+
11,
|
|
2332
|
+
12,
|
|
2333
|
+
13,
|
|
2334
|
+
14,
|
|
2335
|
+
15,
|
|
2336
|
+
14,
|
|
2337
|
+
10,
|
|
2338
|
+
4,
|
|
2339
|
+
8,
|
|
2340
|
+
9,
|
|
2341
|
+
15,
|
|
2342
|
+
13,
|
|
2343
|
+
6,
|
|
2344
|
+
1,
|
|
2345
|
+
12,
|
|
2346
|
+
0,
|
|
2347
|
+
2,
|
|
2348
|
+
11,
|
|
2349
|
+
7,
|
|
2350
|
+
5,
|
|
2351
|
+
3,
|
|
2352
|
+
11,
|
|
2353
|
+
8,
|
|
2354
|
+
12,
|
|
2355
|
+
0,
|
|
2356
|
+
5,
|
|
2357
|
+
2,
|
|
2358
|
+
15,
|
|
2359
|
+
13,
|
|
2360
|
+
10,
|
|
2361
|
+
14,
|
|
2362
|
+
3,
|
|
2363
|
+
6,
|
|
2364
|
+
7,
|
|
2365
|
+
1,
|
|
2366
|
+
9,
|
|
2367
|
+
4,
|
|
2368
|
+
7,
|
|
2369
|
+
9,
|
|
2370
|
+
3,
|
|
2371
|
+
1,
|
|
2372
|
+
13,
|
|
2373
|
+
12,
|
|
2374
|
+
11,
|
|
2375
|
+
14,
|
|
2376
|
+
2,
|
|
2377
|
+
6,
|
|
2378
|
+
5,
|
|
2379
|
+
10,
|
|
2380
|
+
4,
|
|
2381
|
+
0,
|
|
2382
|
+
15,
|
|
2383
|
+
8,
|
|
2384
|
+
9,
|
|
2385
|
+
0,
|
|
2386
|
+
5,
|
|
2387
|
+
7,
|
|
2388
|
+
2,
|
|
2389
|
+
4,
|
|
2390
|
+
10,
|
|
2391
|
+
15,
|
|
2392
|
+
14,
|
|
2393
|
+
1,
|
|
2394
|
+
11,
|
|
2395
|
+
12,
|
|
2396
|
+
6,
|
|
2397
|
+
8,
|
|
2398
|
+
3,
|
|
2399
|
+
13,
|
|
2400
|
+
2,
|
|
2401
|
+
12,
|
|
2402
|
+
6,
|
|
2403
|
+
10,
|
|
2404
|
+
0,
|
|
2405
|
+
11,
|
|
2406
|
+
8,
|
|
2407
|
+
3,
|
|
2408
|
+
4,
|
|
2409
|
+
13,
|
|
2410
|
+
7,
|
|
2411
|
+
5,
|
|
2412
|
+
15,
|
|
2413
|
+
14,
|
|
2414
|
+
1,
|
|
2415
|
+
9,
|
|
2416
|
+
12,
|
|
2417
|
+
5,
|
|
2418
|
+
1,
|
|
2419
|
+
15,
|
|
2420
|
+
14,
|
|
2421
|
+
13,
|
|
2422
|
+
4,
|
|
2423
|
+
10,
|
|
2424
|
+
0,
|
|
2425
|
+
7,
|
|
2426
|
+
6,
|
|
2427
|
+
3,
|
|
2428
|
+
9,
|
|
2429
|
+
2,
|
|
2430
|
+
8,
|
|
2431
|
+
11,
|
|
2432
|
+
13,
|
|
2433
|
+
11,
|
|
2434
|
+
7,
|
|
2435
|
+
14,
|
|
2436
|
+
12,
|
|
2437
|
+
1,
|
|
2438
|
+
3,
|
|
2439
|
+
9,
|
|
2440
|
+
5,
|
|
2441
|
+
0,
|
|
2442
|
+
15,
|
|
2443
|
+
4,
|
|
2444
|
+
8,
|
|
2445
|
+
6,
|
|
2446
|
+
2,
|
|
2447
|
+
10,
|
|
2448
|
+
6,
|
|
2449
|
+
15,
|
|
2450
|
+
14,
|
|
2451
|
+
9,
|
|
2452
|
+
11,
|
|
2453
|
+
3,
|
|
2454
|
+
0,
|
|
2455
|
+
8,
|
|
2456
|
+
12,
|
|
2457
|
+
2,
|
|
2458
|
+
13,
|
|
2459
|
+
7,
|
|
2460
|
+
1,
|
|
2461
|
+
4,
|
|
2462
|
+
10,
|
|
2463
|
+
5,
|
|
2464
|
+
10,
|
|
2465
|
+
2,
|
|
2466
|
+
8,
|
|
2467
|
+
4,
|
|
2468
|
+
7,
|
|
2469
|
+
6,
|
|
2470
|
+
1,
|
|
2471
|
+
5,
|
|
2472
|
+
15,
|
|
2473
|
+
11,
|
|
2474
|
+
9,
|
|
2475
|
+
14,
|
|
2476
|
+
3,
|
|
2477
|
+
12,
|
|
2478
|
+
13,
|
|
2479
|
+
0,
|
|
2480
|
+
0,
|
|
2481
|
+
1,
|
|
2482
|
+
2,
|
|
2483
|
+
3,
|
|
2484
|
+
4,
|
|
2485
|
+
5,
|
|
2486
|
+
6,
|
|
2487
|
+
7,
|
|
2488
|
+
8,
|
|
2489
|
+
9,
|
|
2490
|
+
10,
|
|
2491
|
+
11,
|
|
2492
|
+
12,
|
|
2493
|
+
13,
|
|
2494
|
+
14,
|
|
2495
|
+
15,
|
|
2496
|
+
14,
|
|
2497
|
+
10,
|
|
2498
|
+
4,
|
|
2499
|
+
8,
|
|
2500
|
+
9,
|
|
2501
|
+
15,
|
|
2502
|
+
13,
|
|
2503
|
+
6,
|
|
2504
|
+
1,
|
|
2505
|
+
12,
|
|
2506
|
+
0,
|
|
2507
|
+
2,
|
|
2508
|
+
11,
|
|
2509
|
+
7,
|
|
2510
|
+
5,
|
|
2511
|
+
3,
|
|
2512
|
+
// Blake1, unused in others
|
|
2513
|
+
11,
|
|
2514
|
+
8,
|
|
2515
|
+
12,
|
|
2516
|
+
0,
|
|
2517
|
+
5,
|
|
2518
|
+
2,
|
|
2519
|
+
15,
|
|
2520
|
+
13,
|
|
2521
|
+
10,
|
|
2522
|
+
14,
|
|
2523
|
+
3,
|
|
2524
|
+
6,
|
|
2525
|
+
7,
|
|
2526
|
+
1,
|
|
2527
|
+
9,
|
|
2528
|
+
4,
|
|
2529
|
+
7,
|
|
2530
|
+
9,
|
|
2531
|
+
3,
|
|
2532
|
+
1,
|
|
2533
|
+
13,
|
|
2534
|
+
12,
|
|
2535
|
+
11,
|
|
2536
|
+
14,
|
|
2537
|
+
2,
|
|
2538
|
+
6,
|
|
2539
|
+
5,
|
|
2540
|
+
10,
|
|
2541
|
+
4,
|
|
2542
|
+
0,
|
|
2543
|
+
15,
|
|
2544
|
+
8,
|
|
2545
|
+
9,
|
|
2546
|
+
0,
|
|
2547
|
+
5,
|
|
2548
|
+
7,
|
|
2549
|
+
2,
|
|
2550
|
+
4,
|
|
2551
|
+
10,
|
|
2552
|
+
15,
|
|
2553
|
+
14,
|
|
2554
|
+
1,
|
|
2555
|
+
11,
|
|
2556
|
+
12,
|
|
2557
|
+
6,
|
|
2558
|
+
8,
|
|
2559
|
+
3,
|
|
2560
|
+
13,
|
|
2561
|
+
2,
|
|
2562
|
+
12,
|
|
2563
|
+
6,
|
|
2564
|
+
10,
|
|
2565
|
+
0,
|
|
2566
|
+
11,
|
|
2567
|
+
8,
|
|
2568
|
+
3,
|
|
2569
|
+
4,
|
|
2570
|
+
13,
|
|
2571
|
+
7,
|
|
2572
|
+
5,
|
|
2573
|
+
15,
|
|
2574
|
+
14,
|
|
2575
|
+
1,
|
|
2576
|
+
9
|
|
2577
|
+
]);
|
|
2578
|
+
function G1s(a, b, c, d, x) {
|
|
2579
|
+
a = a + b + x | 0;
|
|
2580
|
+
d = rotr(d ^ a, 16);
|
|
2581
|
+
c = c + d | 0;
|
|
2582
|
+
b = rotr(b ^ c, 12);
|
|
2583
|
+
return { a, b, c, d };
|
|
2584
|
+
}
|
|
2585
|
+
function G2s(a, b, c, d, x) {
|
|
2586
|
+
a = a + b + x | 0;
|
|
2587
|
+
d = rotr(d ^ a, 8);
|
|
2588
|
+
c = c + d | 0;
|
|
2589
|
+
b = rotr(b ^ c, 7);
|
|
2590
|
+
return { a, b, c, d };
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
// ../../node_modules/@noble/hashes/blake2.js
|
|
2594
|
+
function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) {
|
|
2595
|
+
anumber(keyLen);
|
|
2596
|
+
if (outputLen <= 0 || outputLen > keyLen)
|
|
2597
|
+
throw new Error("outputLen bigger than keyLen");
|
|
2598
|
+
const { key, salt, personalization } = opts;
|
|
2599
|
+
if (key !== void 0 && (key.length < 1 || key.length > keyLen))
|
|
2600
|
+
throw new Error('"key" expected to be undefined or of length=1..' + keyLen);
|
|
2601
|
+
if (salt !== void 0)
|
|
2602
|
+
abytes(salt, saltLen, "salt");
|
|
2603
|
+
if (personalization !== void 0)
|
|
2604
|
+
abytes(personalization, persLen, "personalization");
|
|
2605
|
+
}
|
|
2606
|
+
var _BLAKE2 = class {
|
|
2607
|
+
buffer;
|
|
2608
|
+
buffer32;
|
|
2609
|
+
finished = false;
|
|
2610
|
+
destroyed = false;
|
|
2611
|
+
length = 0;
|
|
2612
|
+
pos = 0;
|
|
2613
|
+
blockLen;
|
|
2614
|
+
outputLen;
|
|
2615
|
+
canXOF = false;
|
|
2616
|
+
constructor(blockLen, outputLen) {
|
|
2617
|
+
anumber(blockLen);
|
|
2618
|
+
anumber(outputLen);
|
|
2619
|
+
this.blockLen = blockLen;
|
|
2620
|
+
this.outputLen = outputLen;
|
|
2621
|
+
this.buffer = new Uint8Array(blockLen);
|
|
2622
|
+
this.buffer32 = u32(this.buffer);
|
|
2623
|
+
}
|
|
2624
|
+
update(data) {
|
|
2625
|
+
aexists(this);
|
|
2626
|
+
abytes(data);
|
|
2627
|
+
const { blockLen, buffer, buffer32 } = this;
|
|
2628
|
+
const len = data.length;
|
|
2629
|
+
const offset = data.byteOffset;
|
|
2630
|
+
const buf = data.buffer;
|
|
2631
|
+
for (let pos = 0; pos < len; ) {
|
|
2632
|
+
if (this.pos === blockLen) {
|
|
2633
|
+
swap32IfBE(buffer32);
|
|
2634
|
+
this.compress(buffer32, 0, false);
|
|
2635
|
+
swap32IfBE(buffer32);
|
|
2636
|
+
this.pos = 0;
|
|
2637
|
+
}
|
|
2638
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
2639
|
+
const dataOffset = offset + pos;
|
|
2640
|
+
if (take === blockLen && !(dataOffset % 4) && pos + take < len) {
|
|
2641
|
+
const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4));
|
|
2642
|
+
swap32IfBE(data32);
|
|
2643
|
+
for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) {
|
|
2644
|
+
this.length += blockLen;
|
|
2645
|
+
this.compress(data32, pos32, false);
|
|
2646
|
+
}
|
|
2647
|
+
swap32IfBE(data32);
|
|
2648
|
+
continue;
|
|
2649
|
+
}
|
|
2650
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
2651
|
+
this.pos += take;
|
|
2652
|
+
this.length += take;
|
|
2653
|
+
pos += take;
|
|
2654
|
+
}
|
|
2655
|
+
return this;
|
|
2656
|
+
}
|
|
2657
|
+
digestInto(out) {
|
|
2658
|
+
aexists(this);
|
|
2659
|
+
aoutput(out, this);
|
|
2660
|
+
const { pos, buffer32 } = this;
|
|
2661
|
+
this.finished = true;
|
|
2662
|
+
clean(this.buffer.subarray(pos));
|
|
2663
|
+
swap32IfBE(buffer32);
|
|
2664
|
+
this.compress(buffer32, 0, true);
|
|
2665
|
+
swap32IfBE(buffer32);
|
|
2666
|
+
if (out.byteOffset & 3)
|
|
2667
|
+
throw new RangeError('"digestInto() output" expected 4-byte aligned byteOffset, got ' + out.byteOffset);
|
|
2668
|
+
const state = this.get();
|
|
2669
|
+
const out32 = u32(out);
|
|
2670
|
+
const full = Math.floor(this.outputLen / 4);
|
|
2671
|
+
for (let i = 0; i < full; i++)
|
|
2672
|
+
out32[i] = swap8IfBE(state[i]);
|
|
2673
|
+
const tail = this.outputLen % 4;
|
|
2674
|
+
if (!tail)
|
|
2675
|
+
return;
|
|
2676
|
+
const off = full * 4;
|
|
2677
|
+
const word = state[full];
|
|
2678
|
+
for (let i = 0; i < tail; i++)
|
|
2679
|
+
out[off + i] = word >>> 8 * i;
|
|
2680
|
+
}
|
|
2681
|
+
digest() {
|
|
2682
|
+
const { buffer, outputLen } = this;
|
|
2683
|
+
this.digestInto(buffer);
|
|
2684
|
+
const res = buffer.slice(0, outputLen);
|
|
2685
|
+
this.destroy();
|
|
2686
|
+
return res;
|
|
2687
|
+
}
|
|
2688
|
+
_cloneInto(to) {
|
|
2689
|
+
const { buffer, length, finished, destroyed, outputLen, pos } = this;
|
|
2690
|
+
to ||= new this.constructor({ dkLen: outputLen });
|
|
2691
|
+
to.set(...this.get());
|
|
2692
|
+
to.buffer.set(buffer);
|
|
2693
|
+
to.destroyed = destroyed;
|
|
2694
|
+
to.finished = finished;
|
|
2695
|
+
to.length = length;
|
|
2696
|
+
to.pos = pos;
|
|
2697
|
+
to.outputLen = outputLen;
|
|
2698
|
+
return to;
|
|
2699
|
+
}
|
|
2700
|
+
clone() {
|
|
2701
|
+
return this._cloneInto();
|
|
2702
|
+
}
|
|
2703
|
+
};
|
|
2704
|
+
function compress(s, offset, msg, rounds, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) {
|
|
2705
|
+
let j = 0;
|
|
2706
|
+
for (let i = 0; i < rounds; i++) {
|
|
2707
|
+
({ a: v0, b: v4, c: v8, d: v12 } = G1s(v0, v4, v8, v12, msg[offset + s[j++]]));
|
|
2708
|
+
({ a: v0, b: v4, c: v8, d: v12 } = G2s(v0, v4, v8, v12, msg[offset + s[j++]]));
|
|
2709
|
+
({ a: v1, b: v5, c: v9, d: v13 } = G1s(v1, v5, v9, v13, msg[offset + s[j++]]));
|
|
2710
|
+
({ a: v1, b: v5, c: v9, d: v13 } = G2s(v1, v5, v9, v13, msg[offset + s[j++]]));
|
|
2711
|
+
({ a: v2, b: v6, c: v10, d: v14 } = G1s(v2, v6, v10, v14, msg[offset + s[j++]]));
|
|
2712
|
+
({ a: v2, b: v6, c: v10, d: v14 } = G2s(v2, v6, v10, v14, msg[offset + s[j++]]));
|
|
2713
|
+
({ a: v3, b: v7, c: v11, d: v15 } = G1s(v3, v7, v11, v15, msg[offset + s[j++]]));
|
|
2714
|
+
({ a: v3, b: v7, c: v11, d: v15 } = G2s(v3, v7, v11, v15, msg[offset + s[j++]]));
|
|
2715
|
+
({ a: v0, b: v5, c: v10, d: v15 } = G1s(v0, v5, v10, v15, msg[offset + s[j++]]));
|
|
2716
|
+
({ a: v0, b: v5, c: v10, d: v15 } = G2s(v0, v5, v10, v15, msg[offset + s[j++]]));
|
|
2717
|
+
({ a: v1, b: v6, c: v11, d: v12 } = G1s(v1, v6, v11, v12, msg[offset + s[j++]]));
|
|
2718
|
+
({ a: v1, b: v6, c: v11, d: v12 } = G2s(v1, v6, v11, v12, msg[offset + s[j++]]));
|
|
2719
|
+
({ a: v2, b: v7, c: v8, d: v13 } = G1s(v2, v7, v8, v13, msg[offset + s[j++]]));
|
|
2720
|
+
({ a: v2, b: v7, c: v8, d: v13 } = G2s(v2, v7, v8, v13, msg[offset + s[j++]]));
|
|
2721
|
+
({ a: v3, b: v4, c: v9, d: v14 } = G1s(v3, v4, v9, v14, msg[offset + s[j++]]));
|
|
2722
|
+
({ a: v3, b: v4, c: v9, d: v14 } = G2s(v3, v4, v9, v14, msg[offset + s[j++]]));
|
|
2723
|
+
}
|
|
2724
|
+
return { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 };
|
|
2725
|
+
}
|
|
2726
|
+
var B2S_IV = /* @__PURE__ */ SHA256_IV.slice();
|
|
2727
|
+
var _BLAKE2s = class extends _BLAKE2 {
|
|
2728
|
+
// Internal state, same as SHA-256
|
|
2729
|
+
v0 = B2S_IV[0] | 0;
|
|
2730
|
+
v1 = B2S_IV[1] | 0;
|
|
2731
|
+
v2 = B2S_IV[2] | 0;
|
|
2732
|
+
v3 = B2S_IV[3] | 0;
|
|
2733
|
+
v4 = B2S_IV[4] | 0;
|
|
2734
|
+
v5 = B2S_IV[5] | 0;
|
|
2735
|
+
v6 = B2S_IV[6] | 0;
|
|
2736
|
+
v7 = B2S_IV[7] | 0;
|
|
2737
|
+
constructor(opts = {}) {
|
|
2738
|
+
const olen = opts.dkLen === void 0 ? 32 : opts.dkLen;
|
|
2739
|
+
super(64, olen);
|
|
2740
|
+
checkBlake2Opts(olen, opts, 32, 8, 8);
|
|
2741
|
+
let { key, personalization, salt } = opts;
|
|
2742
|
+
let keyLength = 0;
|
|
2743
|
+
if (key !== void 0) {
|
|
2744
|
+
abytes(key, void 0, "key");
|
|
2745
|
+
keyLength = key.length;
|
|
2746
|
+
}
|
|
2747
|
+
this.v0 ^= this.outputLen | keyLength << 8 | 1 << 16 | 1 << 24;
|
|
2748
|
+
if (salt !== void 0) {
|
|
2749
|
+
abytes(salt, void 0, "salt");
|
|
2750
|
+
const slt = u32(salt);
|
|
2751
|
+
this.v4 ^= swap8IfBE(slt[0]);
|
|
2752
|
+
this.v5 ^= swap8IfBE(slt[1]);
|
|
2753
|
+
}
|
|
2754
|
+
if (personalization !== void 0) {
|
|
2755
|
+
abytes(personalization, void 0, "personalization");
|
|
2756
|
+
const pers = u32(personalization);
|
|
2757
|
+
this.v6 ^= swap8IfBE(pers[0]);
|
|
2758
|
+
this.v7 ^= swap8IfBE(pers[1]);
|
|
2759
|
+
}
|
|
2760
|
+
if (key !== void 0) {
|
|
2761
|
+
const tmp = new Uint8Array(this.blockLen);
|
|
2762
|
+
tmp.set(key);
|
|
2763
|
+
this.update(tmp);
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2766
|
+
get() {
|
|
2767
|
+
const { v0, v1, v2, v3, v4, v5, v6, v7 } = this;
|
|
2768
|
+
return [v0, v1, v2, v3, v4, v5, v6, v7];
|
|
2769
|
+
}
|
|
2770
|
+
// prettier-ignore
|
|
2771
|
+
set(v0, v1, v2, v3, v4, v5, v6, v7) {
|
|
2772
|
+
this.v0 = v0 | 0;
|
|
2773
|
+
this.v1 = v1 | 0;
|
|
2774
|
+
this.v2 = v2 | 0;
|
|
2775
|
+
this.v3 = v3 | 0;
|
|
2776
|
+
this.v4 = v4 | 0;
|
|
2777
|
+
this.v5 = v5 | 0;
|
|
2778
|
+
this.v6 = v6 | 0;
|
|
2779
|
+
this.v7 = v7 | 0;
|
|
2780
|
+
}
|
|
2781
|
+
compress(msg, offset, isLast) {
|
|
2782
|
+
const { h, l } = fromBig(BigInt(this.length));
|
|
2783
|
+
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(BSIGMA, offset, msg, 10, this.v0, this.v1, this.v2, this.v3, this.v4, this.v5, this.v6, this.v7, B2S_IV[0], B2S_IV[1], B2S_IV[2], B2S_IV[3], l ^ B2S_IV[4], h ^ B2S_IV[5], isLast ? ~B2S_IV[6] : B2S_IV[6], B2S_IV[7]);
|
|
2784
|
+
this.v0 ^= v0 ^ v8;
|
|
2785
|
+
this.v1 ^= v1 ^ v9;
|
|
2786
|
+
this.v2 ^= v2 ^ v10;
|
|
2787
|
+
this.v3 ^= v3 ^ v11;
|
|
2788
|
+
this.v4 ^= v4 ^ v12;
|
|
2789
|
+
this.v5 ^= v5 ^ v13;
|
|
2790
|
+
this.v6 ^= v6 ^ v14;
|
|
2791
|
+
this.v7 ^= v7 ^ v15;
|
|
2792
|
+
}
|
|
2793
|
+
destroy() {
|
|
2794
|
+
this.destroyed = true;
|
|
2795
|
+
clean(this.buffer32);
|
|
2796
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
2797
|
+
}
|
|
2798
|
+
};
|
|
2799
|
+
var blake2s = /* @__PURE__ */ createHasher((opts) => new _BLAKE2s(opts));
|
|
2800
|
+
|
|
2801
|
+
// ../../node_modules/@noble/hashes/hmac.js
|
|
2802
|
+
var _HMAC = class {
|
|
2803
|
+
oHash;
|
|
2804
|
+
iHash;
|
|
2805
|
+
blockLen;
|
|
2806
|
+
outputLen;
|
|
2807
|
+
canXOF = false;
|
|
2808
|
+
finished = false;
|
|
2809
|
+
destroyed = false;
|
|
2810
|
+
constructor(hash, key) {
|
|
2811
|
+
ahash(hash);
|
|
2812
|
+
abytes(key, void 0, "key");
|
|
2813
|
+
this.iHash = hash.create();
|
|
2814
|
+
if (typeof this.iHash.update !== "function")
|
|
2815
|
+
throw new Error("Expected instance of class which extends utils.Hash");
|
|
2816
|
+
this.blockLen = this.iHash.blockLen;
|
|
2817
|
+
this.outputLen = this.iHash.outputLen;
|
|
2818
|
+
const blockLen = this.blockLen;
|
|
2819
|
+
const pad = new Uint8Array(blockLen);
|
|
2820
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
|
2821
|
+
for (let i = 0; i < pad.length; i++)
|
|
2822
|
+
pad[i] ^= 54;
|
|
2823
|
+
this.iHash.update(pad);
|
|
2824
|
+
this.oHash = hash.create();
|
|
2825
|
+
for (let i = 0; i < pad.length; i++)
|
|
2826
|
+
pad[i] ^= 54 ^ 92;
|
|
2827
|
+
this.oHash.update(pad);
|
|
2828
|
+
clean(pad);
|
|
2829
|
+
}
|
|
2830
|
+
update(buf) {
|
|
2831
|
+
aexists(this);
|
|
2832
|
+
this.iHash.update(buf);
|
|
2833
|
+
return this;
|
|
2834
|
+
}
|
|
2835
|
+
digestInto(out) {
|
|
2836
|
+
aexists(this);
|
|
2837
|
+
aoutput(out, this);
|
|
2838
|
+
this.finished = true;
|
|
2839
|
+
const buf = out.subarray(0, this.outputLen);
|
|
2840
|
+
this.iHash.digestInto(buf);
|
|
2841
|
+
this.oHash.update(buf);
|
|
2842
|
+
this.oHash.digestInto(buf);
|
|
2843
|
+
this.destroy();
|
|
2844
|
+
}
|
|
2845
|
+
digest() {
|
|
2846
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
|
2847
|
+
this.digestInto(out);
|
|
2848
|
+
return out;
|
|
2849
|
+
}
|
|
2850
|
+
_cloneInto(to) {
|
|
2851
|
+
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
2852
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
2853
|
+
to = to;
|
|
2854
|
+
to.finished = finished;
|
|
2855
|
+
to.destroyed = destroyed;
|
|
2856
|
+
to.blockLen = blockLen;
|
|
2857
|
+
to.outputLen = outputLen;
|
|
2858
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
|
2859
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
|
2860
|
+
return to;
|
|
2861
|
+
}
|
|
2862
|
+
clone() {
|
|
2863
|
+
return this._cloneInto();
|
|
2864
|
+
}
|
|
2865
|
+
destroy() {
|
|
2866
|
+
this.destroyed = true;
|
|
2867
|
+
this.oHash.destroy();
|
|
2868
|
+
this.iHash.destroy();
|
|
2869
|
+
}
|
|
2870
|
+
};
|
|
2871
|
+
var hmac = /* @__PURE__ */ (() => {
|
|
2872
|
+
const hmac_ = ((hash, key, message) => new _HMAC(hash, key).update(message).digest());
|
|
2873
|
+
hmac_.create = (hash, key) => new _HMAC(hash, key);
|
|
2874
|
+
return hmac_;
|
|
2875
|
+
})();
|
|
2876
|
+
|
|
2877
|
+
// ../../node_modules/@noble/hashes/hkdf.js
|
|
2878
|
+
function extract(hash, ikm, salt) {
|
|
2879
|
+
ahash(hash);
|
|
2880
|
+
if (salt === void 0)
|
|
2881
|
+
salt = new Uint8Array(hash.outputLen);
|
|
2882
|
+
return hmac(hash, salt, ikm);
|
|
2883
|
+
}
|
|
2884
|
+
var HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);
|
|
2885
|
+
var EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();
|
|
2886
|
+
function expand(hash, prk, info, length = 32) {
|
|
2887
|
+
ahash(hash);
|
|
2888
|
+
anumber(length, "length");
|
|
2889
|
+
abytes(prk, void 0, "prk");
|
|
2890
|
+
const olen = hash.outputLen;
|
|
2891
|
+
if (prk.length < olen)
|
|
2892
|
+
throw new Error('"prk" must be at least HashLen octets');
|
|
2893
|
+
if (length > 255 * olen)
|
|
2894
|
+
throw new Error("Length must be <= 255*HashLen");
|
|
2895
|
+
const blocks = Math.ceil(length / olen);
|
|
2896
|
+
if (info === void 0)
|
|
2897
|
+
info = EMPTY_BUFFER;
|
|
2898
|
+
else
|
|
2899
|
+
abytes(info, void 0, "info");
|
|
2900
|
+
const okm = new Uint8Array(blocks * olen);
|
|
2901
|
+
const HMAC = hmac.create(hash, prk);
|
|
2902
|
+
const HMACTmp = HMAC._cloneInto();
|
|
2903
|
+
const T = new Uint8Array(HMAC.outputLen);
|
|
2904
|
+
for (let counter = 0; counter < blocks; counter++) {
|
|
2905
|
+
HKDF_COUNTER[0] = counter + 1;
|
|
2906
|
+
HMACTmp.update(counter === 0 ? EMPTY_BUFFER : T).update(info).update(HKDF_COUNTER).digestInto(T);
|
|
2907
|
+
okm.set(T, olen * counter);
|
|
2908
|
+
HMAC._cloneInto(HMACTmp);
|
|
2909
|
+
}
|
|
2910
|
+
HMAC.destroy();
|
|
2911
|
+
HMACTmp.destroy();
|
|
2912
|
+
clean(T, HKDF_COUNTER);
|
|
2913
|
+
return okm.slice(0, length);
|
|
2914
|
+
}
|
|
2915
|
+
var hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length);
|
|
2916
|
+
|
|
2917
|
+
// ../../node_modules/@noble/ciphers/utils.js
|
|
2918
|
+
function isBytes3(a) {
|
|
2919
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
2920
|
+
}
|
|
2921
|
+
function abool2(b) {
|
|
2922
|
+
if (typeof b !== "boolean")
|
|
2923
|
+
throw new TypeError(`boolean expected, not ${b}`);
|
|
2924
|
+
}
|
|
2925
|
+
function anumber3(n) {
|
|
2926
|
+
if (typeof n !== "number")
|
|
2927
|
+
throw new TypeError("number expected, got " + typeof n);
|
|
2928
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
2929
|
+
throw new RangeError("positive integer expected, got " + n);
|
|
2930
|
+
}
|
|
2931
|
+
function abytes3(value, length, title = "") {
|
|
2932
|
+
const bytes = isBytes3(value);
|
|
2933
|
+
const len = value?.length;
|
|
2934
|
+
const needsLen = length !== void 0;
|
|
2935
|
+
if (!bytes || needsLen && len !== length) {
|
|
2936
|
+
const prefix = title && `"${title}" `;
|
|
2937
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
2938
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
2939
|
+
const message = prefix + "expected Uint8Array" + ofLen + ", got " + got;
|
|
2940
|
+
if (!bytes)
|
|
2941
|
+
throw new TypeError(message);
|
|
2942
|
+
throw new RangeError(message);
|
|
2943
|
+
}
|
|
2944
|
+
return value;
|
|
2945
|
+
}
|
|
2946
|
+
function aexists2(instance, checkFinished = true) {
|
|
2947
|
+
if (instance.destroyed)
|
|
2948
|
+
throw new Error("Hash instance has been destroyed");
|
|
2949
|
+
if (checkFinished && instance.finished)
|
|
2950
|
+
throw new Error("Hash#digest() has already been called");
|
|
2951
|
+
}
|
|
2952
|
+
function aoutput2(out, instance, onlyAligned = false) {
|
|
2953
|
+
abytes3(out, void 0, "output");
|
|
2954
|
+
const min = instance.outputLen;
|
|
2955
|
+
if (out.length < min) {
|
|
2956
|
+
throw new RangeError("digestInto() expects output buffer of length at least " + min);
|
|
2957
|
+
}
|
|
2958
|
+
if (onlyAligned && !isAligned32(out))
|
|
2959
|
+
throw new Error("invalid output, must be aligned");
|
|
2960
|
+
}
|
|
2961
|
+
function u322(arr) {
|
|
2962
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
2963
|
+
}
|
|
2964
|
+
function clean2(...arrays) {
|
|
2965
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
2966
|
+
arrays[i].fill(0);
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
function createView2(arr) {
|
|
2970
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
2971
|
+
}
|
|
2972
|
+
var isLE2 = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
2973
|
+
var byteSwap2 = (word) => word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
2974
|
+
var swap8IfBE2 = isLE2 ? (n) => n : (n) => byteSwap2(n) >>> 0;
|
|
2975
|
+
var byteSwap322 = (arr) => {
|
|
2976
|
+
for (let i = 0; i < arr.length; i++)
|
|
2977
|
+
arr[i] = byteSwap2(arr[i]);
|
|
2978
|
+
return arr;
|
|
2979
|
+
};
|
|
2980
|
+
var swap32IfBE2 = isLE2 ? (u) => u : byteSwap322;
|
|
2981
|
+
function checkOpts(defaults, opts) {
|
|
2982
|
+
if (opts == null || typeof opts !== "object")
|
|
2983
|
+
throw new Error("options must be defined");
|
|
2984
|
+
const merged = Object.assign(defaults, opts);
|
|
2985
|
+
return merged;
|
|
2986
|
+
}
|
|
2987
|
+
function equalBytes2(a, b) {
|
|
2988
|
+
if (a.length !== b.length)
|
|
2989
|
+
return false;
|
|
2990
|
+
let diff = 0;
|
|
2991
|
+
for (let i = 0; i < a.length; i++)
|
|
2992
|
+
diff |= a[i] ^ b[i];
|
|
2993
|
+
return diff === 0;
|
|
2994
|
+
}
|
|
2995
|
+
function wrapMacConstructor(keyLen, macCons, fromMsg) {
|
|
2996
|
+
const mac = macCons;
|
|
2997
|
+
const getArgs = fromMsg || (() => []);
|
|
2998
|
+
const macC = (msg, key) => mac(key, ...getArgs(msg)).update(msg).digest();
|
|
2999
|
+
const tmp = mac(new Uint8Array(keyLen), ...getArgs(new Uint8Array(0)));
|
|
3000
|
+
macC.outputLen = tmp.outputLen;
|
|
3001
|
+
macC.blockLen = tmp.blockLen;
|
|
3002
|
+
macC.create = (key, ...args) => mac(key, ...args);
|
|
3003
|
+
return macC;
|
|
3004
|
+
}
|
|
3005
|
+
var wrapCipher = /* @__NO_SIDE_EFFECTS__ */ (params, constructor) => {
|
|
3006
|
+
function wrappedCipher(key, ...args) {
|
|
3007
|
+
abytes3(key, void 0, "key");
|
|
3008
|
+
if (params.nonceLength !== void 0) {
|
|
3009
|
+
const nonce = args[0];
|
|
3010
|
+
abytes3(nonce, params.varSizeNonce ? void 0 : params.nonceLength, "nonce");
|
|
3011
|
+
}
|
|
3012
|
+
const tagl = params.tagLength;
|
|
3013
|
+
if (tagl && args[1] !== void 0)
|
|
3014
|
+
abytes3(args[1], void 0, "AAD");
|
|
3015
|
+
const cipher = constructor(key, ...args);
|
|
3016
|
+
const checkOutput = (fnLength, output) => {
|
|
3017
|
+
if (output !== void 0) {
|
|
3018
|
+
if (fnLength !== 2)
|
|
3019
|
+
throw new Error("cipher output not supported");
|
|
3020
|
+
abytes3(output, void 0, "output");
|
|
3021
|
+
}
|
|
3022
|
+
};
|
|
3023
|
+
let called = false;
|
|
3024
|
+
const wrCipher = {
|
|
3025
|
+
encrypt(data, output) {
|
|
3026
|
+
if (called)
|
|
3027
|
+
throw new Error("cannot encrypt() twice with same key + nonce");
|
|
3028
|
+
called = true;
|
|
3029
|
+
abytes3(data);
|
|
3030
|
+
checkOutput(cipher.encrypt.length, output);
|
|
3031
|
+
return cipher.encrypt(data, output);
|
|
3032
|
+
},
|
|
3033
|
+
decrypt(data, output) {
|
|
3034
|
+
abytes3(data);
|
|
3035
|
+
if (tagl && data.length < tagl)
|
|
3036
|
+
throw new Error('"ciphertext" expected length bigger than tagLength=' + tagl);
|
|
3037
|
+
checkOutput(cipher.decrypt.length, output);
|
|
3038
|
+
return cipher.decrypt(data, output);
|
|
3039
|
+
}
|
|
3040
|
+
};
|
|
3041
|
+
return wrCipher;
|
|
3042
|
+
}
|
|
3043
|
+
Object.assign(wrappedCipher, params);
|
|
3044
|
+
return wrappedCipher;
|
|
3045
|
+
};
|
|
3046
|
+
function getOutput(expectedLength, out, onlyAligned = true) {
|
|
3047
|
+
if (out === void 0)
|
|
3048
|
+
return new Uint8Array(expectedLength);
|
|
3049
|
+
abytes3(out, void 0, "output");
|
|
3050
|
+
if (out.length !== expectedLength)
|
|
3051
|
+
throw new Error('"output" expected Uint8Array of length ' + expectedLength + ", got: " + out.length);
|
|
3052
|
+
if (onlyAligned && !isAligned32(out))
|
|
3053
|
+
throw new Error("invalid output, must be aligned");
|
|
3054
|
+
return out;
|
|
3055
|
+
}
|
|
3056
|
+
function u64Lengths(dataLength, aadLength, isLE3) {
|
|
3057
|
+
anumber3(dataLength);
|
|
3058
|
+
anumber3(aadLength);
|
|
3059
|
+
abool2(isLE3);
|
|
3060
|
+
const num = new Uint8Array(16);
|
|
3061
|
+
const view = createView2(num);
|
|
3062
|
+
view.setBigUint64(0, BigInt(aadLength), isLE3);
|
|
3063
|
+
view.setBigUint64(8, BigInt(dataLength), isLE3);
|
|
3064
|
+
return num;
|
|
3065
|
+
}
|
|
3066
|
+
function isAligned32(bytes) {
|
|
3067
|
+
return bytes.byteOffset % 4 === 0;
|
|
3068
|
+
}
|
|
3069
|
+
function copyBytes2(bytes) {
|
|
3070
|
+
return Uint8Array.from(abytes3(bytes));
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
// ../../node_modules/@noble/ciphers/_arx.js
|
|
3074
|
+
var encodeStr = (str) => Uint8Array.from(str.split(""), (c) => c.charCodeAt(0));
|
|
3075
|
+
var sigma16_32 = /* @__PURE__ */ (() => swap32IfBE2(u322(encodeStr("expand 16-byte k"))))();
|
|
3076
|
+
var sigma32_32 = /* @__PURE__ */ (() => swap32IfBE2(u322(encodeStr("expand 32-byte k"))))();
|
|
3077
|
+
function rotl(a, b) {
|
|
3078
|
+
return a << b | a >>> 32 - b;
|
|
3079
|
+
}
|
|
3080
|
+
var BLOCK_LEN = 64;
|
|
3081
|
+
var BLOCK_LEN32 = 16;
|
|
3082
|
+
var MAX_COUNTER = /* @__PURE__ */ (() => 2 ** 32 - 1)();
|
|
3083
|
+
var U32_EMPTY = /* @__PURE__ */ Uint32Array.of();
|
|
3084
|
+
function runCipher(core, sigma, key, nonce, data, output, counter, rounds) {
|
|
3085
|
+
const len = data.length;
|
|
3086
|
+
const block = new Uint8Array(BLOCK_LEN);
|
|
3087
|
+
const b32 = u322(block);
|
|
3088
|
+
const isAligned = isLE2 && isAligned32(data) && isAligned32(output);
|
|
3089
|
+
const d32 = isAligned ? u322(data) : U32_EMPTY;
|
|
3090
|
+
const o32 = isAligned ? u322(output) : U32_EMPTY;
|
|
3091
|
+
if (!isLE2) {
|
|
3092
|
+
for (let pos = 0; pos < len; counter++) {
|
|
3093
|
+
core(sigma, key, nonce, b32, counter, rounds);
|
|
3094
|
+
swap32IfBE2(b32);
|
|
3095
|
+
if (counter >= MAX_COUNTER)
|
|
3096
|
+
throw new Error("arx: counter overflow");
|
|
3097
|
+
const take = Math.min(BLOCK_LEN, len - pos);
|
|
3098
|
+
for (let j = 0, posj; j < take; j++) {
|
|
3099
|
+
posj = pos + j;
|
|
3100
|
+
output[posj] = data[posj] ^ block[j];
|
|
3101
|
+
}
|
|
3102
|
+
pos += take;
|
|
3103
|
+
}
|
|
3104
|
+
return;
|
|
3105
|
+
}
|
|
3106
|
+
for (let pos = 0; pos < len; counter++) {
|
|
3107
|
+
core(sigma, key, nonce, b32, counter, rounds);
|
|
3108
|
+
if (counter >= MAX_COUNTER)
|
|
3109
|
+
throw new Error("arx: counter overflow");
|
|
3110
|
+
const take = Math.min(BLOCK_LEN, len - pos);
|
|
3111
|
+
if (isAligned && take === BLOCK_LEN) {
|
|
3112
|
+
const pos32 = pos / 4;
|
|
3113
|
+
if (pos % 4 !== 0)
|
|
3114
|
+
throw new Error("arx: invalid block position");
|
|
3115
|
+
for (let j = 0, posj; j < BLOCK_LEN32; j++) {
|
|
3116
|
+
posj = pos32 + j;
|
|
3117
|
+
o32[posj] = d32[posj] ^ b32[j];
|
|
3118
|
+
}
|
|
3119
|
+
pos += BLOCK_LEN;
|
|
3120
|
+
continue;
|
|
3121
|
+
}
|
|
3122
|
+
for (let j = 0, posj; j < take; j++) {
|
|
3123
|
+
posj = pos + j;
|
|
3124
|
+
output[posj] = data[posj] ^ block[j];
|
|
3125
|
+
}
|
|
3126
|
+
pos += take;
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
function createCipher(core, opts) {
|
|
3130
|
+
const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({ allowShortKeys: false, counterLength: 8, counterRight: false, rounds: 20 }, opts);
|
|
3131
|
+
if (typeof core !== "function")
|
|
3132
|
+
throw new Error("core must be a function");
|
|
3133
|
+
anumber3(counterLength);
|
|
3134
|
+
anumber3(rounds);
|
|
3135
|
+
abool2(counterRight);
|
|
3136
|
+
abool2(allowShortKeys);
|
|
3137
|
+
return (key, nonce, data, output, counter = 0) => {
|
|
3138
|
+
abytes3(key, void 0, "key");
|
|
3139
|
+
abytes3(nonce, void 0, "nonce");
|
|
3140
|
+
abytes3(data, void 0, "data");
|
|
3141
|
+
const len = data.length;
|
|
3142
|
+
output = getOutput(len, output, false);
|
|
3143
|
+
anumber3(counter);
|
|
3144
|
+
if (counter < 0 || counter >= MAX_COUNTER)
|
|
3145
|
+
throw new Error("arx: counter overflow");
|
|
3146
|
+
const toClean = [];
|
|
3147
|
+
let l = key.length;
|
|
3148
|
+
let k;
|
|
3149
|
+
let sigma;
|
|
3150
|
+
if (l === 32) {
|
|
3151
|
+
toClean.push(k = copyBytes2(key));
|
|
3152
|
+
sigma = sigma32_32;
|
|
3153
|
+
} else if (l === 16 && allowShortKeys) {
|
|
3154
|
+
k = new Uint8Array(32);
|
|
3155
|
+
k.set(key);
|
|
3156
|
+
k.set(key, 16);
|
|
3157
|
+
sigma = sigma16_32;
|
|
3158
|
+
toClean.push(k);
|
|
3159
|
+
} else {
|
|
3160
|
+
abytes3(key, 32, "arx key");
|
|
3161
|
+
throw new Error("invalid key size");
|
|
3162
|
+
}
|
|
3163
|
+
if (!isLE2 || !isAligned32(nonce))
|
|
3164
|
+
toClean.push(nonce = copyBytes2(nonce));
|
|
3165
|
+
let k32 = u322(k);
|
|
3166
|
+
if (extendNonceFn) {
|
|
3167
|
+
if (nonce.length !== 24)
|
|
3168
|
+
throw new Error(`arx: extended nonce must be 24 bytes`);
|
|
3169
|
+
const n16 = nonce.subarray(0, 16);
|
|
3170
|
+
if (isLE2)
|
|
3171
|
+
extendNonceFn(sigma, k32, u322(n16), k32);
|
|
3172
|
+
else {
|
|
3173
|
+
const sigmaRaw = swap32IfBE2(Uint32Array.from(sigma));
|
|
3174
|
+
extendNonceFn(sigmaRaw, k32, u322(n16), k32);
|
|
3175
|
+
clean2(sigmaRaw);
|
|
3176
|
+
swap32IfBE2(k32);
|
|
3177
|
+
}
|
|
3178
|
+
nonce = nonce.subarray(16);
|
|
3179
|
+
} else if (!isLE2)
|
|
3180
|
+
swap32IfBE2(k32);
|
|
3181
|
+
const nonceNcLen = 16 - counterLength;
|
|
3182
|
+
if (nonceNcLen !== nonce.length)
|
|
3183
|
+
throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);
|
|
3184
|
+
if (nonceNcLen !== 12) {
|
|
3185
|
+
const nc = new Uint8Array(12);
|
|
3186
|
+
nc.set(nonce, counterRight ? 0 : 12 - nonce.length);
|
|
3187
|
+
nonce = nc;
|
|
3188
|
+
toClean.push(nonce);
|
|
3189
|
+
}
|
|
3190
|
+
const n32 = swap32IfBE2(u322(nonce));
|
|
3191
|
+
try {
|
|
3192
|
+
runCipher(core, sigma, k32, n32, data, output, counter, rounds);
|
|
3193
|
+
return output;
|
|
3194
|
+
} finally {
|
|
3195
|
+
clean2(...toClean);
|
|
3196
|
+
}
|
|
3197
|
+
};
|
|
3198
|
+
}
|
|
3199
|
+
|
|
3200
|
+
// ../../node_modules/@noble/ciphers/_poly1305.js
|
|
3201
|
+
function u8to16(a, i) {
|
|
3202
|
+
return a[i++] & 255 | (a[i++] & 255) << 8;
|
|
3203
|
+
}
|
|
3204
|
+
var Poly1305 = class {
|
|
3205
|
+
blockLen = 16;
|
|
3206
|
+
outputLen = 16;
|
|
3207
|
+
buffer = new Uint8Array(16);
|
|
3208
|
+
r = new Uint16Array(10);
|
|
3209
|
+
// Allocating 1 array with .subarray() here is slower than 3
|
|
3210
|
+
h = new Uint16Array(10);
|
|
3211
|
+
pad = new Uint16Array(8);
|
|
3212
|
+
pos = 0;
|
|
3213
|
+
finished = false;
|
|
3214
|
+
destroyed = false;
|
|
3215
|
+
// Can be speed-up using BigUint64Array, at the cost of complexity
|
|
3216
|
+
constructor(key) {
|
|
3217
|
+
key = copyBytes2(abytes3(key, 32, "key"));
|
|
3218
|
+
const t0 = u8to16(key, 0);
|
|
3219
|
+
const t1 = u8to16(key, 2);
|
|
3220
|
+
const t2 = u8to16(key, 4);
|
|
3221
|
+
const t3 = u8to16(key, 6);
|
|
3222
|
+
const t4 = u8to16(key, 8);
|
|
3223
|
+
const t5 = u8to16(key, 10);
|
|
3224
|
+
const t6 = u8to16(key, 12);
|
|
3225
|
+
const t7 = u8to16(key, 14);
|
|
3226
|
+
this.r[0] = t0 & 8191;
|
|
3227
|
+
this.r[1] = (t0 >>> 13 | t1 << 3) & 8191;
|
|
3228
|
+
this.r[2] = (t1 >>> 10 | t2 << 6) & 7939;
|
|
3229
|
+
this.r[3] = (t2 >>> 7 | t3 << 9) & 8191;
|
|
3230
|
+
this.r[4] = (t3 >>> 4 | t4 << 12) & 255;
|
|
3231
|
+
this.r[5] = t4 >>> 1 & 8190;
|
|
3232
|
+
this.r[6] = (t4 >>> 14 | t5 << 2) & 8191;
|
|
3233
|
+
this.r[7] = (t5 >>> 11 | t6 << 5) & 8065;
|
|
3234
|
+
this.r[8] = (t6 >>> 8 | t7 << 8) & 8191;
|
|
3235
|
+
this.r[9] = t7 >>> 5 & 127;
|
|
3236
|
+
for (let i = 0; i < 8; i++)
|
|
3237
|
+
this.pad[i] = u8to16(key, 16 + 2 * i);
|
|
3238
|
+
}
|
|
3239
|
+
process(data, offset, isLast = false) {
|
|
3240
|
+
const hibit = isLast ? 0 : 1 << 11;
|
|
3241
|
+
const { h, r } = this;
|
|
3242
|
+
const r0 = r[0];
|
|
3243
|
+
const r1 = r[1];
|
|
3244
|
+
const r2 = r[2];
|
|
3245
|
+
const r3 = r[3];
|
|
3246
|
+
const r4 = r[4];
|
|
3247
|
+
const r5 = r[5];
|
|
3248
|
+
const r6 = r[6];
|
|
3249
|
+
const r7 = r[7];
|
|
3250
|
+
const r8 = r[8];
|
|
3251
|
+
const r9 = r[9];
|
|
3252
|
+
const t0 = u8to16(data, offset + 0);
|
|
3253
|
+
const t1 = u8to16(data, offset + 2);
|
|
3254
|
+
const t2 = u8to16(data, offset + 4);
|
|
3255
|
+
const t3 = u8to16(data, offset + 6);
|
|
3256
|
+
const t4 = u8to16(data, offset + 8);
|
|
3257
|
+
const t5 = u8to16(data, offset + 10);
|
|
3258
|
+
const t6 = u8to16(data, offset + 12);
|
|
3259
|
+
const t7 = u8to16(data, offset + 14);
|
|
3260
|
+
let h0 = h[0] + (t0 & 8191);
|
|
3261
|
+
let h1 = h[1] + ((t0 >>> 13 | t1 << 3) & 8191);
|
|
3262
|
+
let h2 = h[2] + ((t1 >>> 10 | t2 << 6) & 8191);
|
|
3263
|
+
let h3 = h[3] + ((t2 >>> 7 | t3 << 9) & 8191);
|
|
3264
|
+
let h4 = h[4] + ((t3 >>> 4 | t4 << 12) & 8191);
|
|
3265
|
+
let h5 = h[5] + (t4 >>> 1 & 8191);
|
|
3266
|
+
let h6 = h[6] + ((t4 >>> 14 | t5 << 2) & 8191);
|
|
3267
|
+
let h7 = h[7] + ((t5 >>> 11 | t6 << 5) & 8191);
|
|
3268
|
+
let h8 = h[8] + ((t6 >>> 8 | t7 << 8) & 8191);
|
|
3269
|
+
let h9 = h[9] + (t7 >>> 5 | hibit);
|
|
3270
|
+
let c = 0;
|
|
3271
|
+
let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) + h4 * (5 * r6);
|
|
3272
|
+
c = d0 >>> 13;
|
|
3273
|
+
d0 &= 8191;
|
|
3274
|
+
d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) + h9 * (5 * r1);
|
|
3275
|
+
c += d0 >>> 13;
|
|
3276
|
+
d0 &= 8191;
|
|
3277
|
+
let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) + h4 * (5 * r7);
|
|
3278
|
+
c = d1 >>> 13;
|
|
3279
|
+
d1 &= 8191;
|
|
3280
|
+
d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) + h9 * (5 * r2);
|
|
3281
|
+
c += d1 >>> 13;
|
|
3282
|
+
d1 &= 8191;
|
|
3283
|
+
let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);
|
|
3284
|
+
c = d2 >>> 13;
|
|
3285
|
+
d2 &= 8191;
|
|
3286
|
+
d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) + h9 * (5 * r3);
|
|
3287
|
+
c += d2 >>> 13;
|
|
3288
|
+
d2 &= 8191;
|
|
3289
|
+
let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);
|
|
3290
|
+
c = d3 >>> 13;
|
|
3291
|
+
d3 &= 8191;
|
|
3292
|
+
d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) + h9 * (5 * r4);
|
|
3293
|
+
c += d3 >>> 13;
|
|
3294
|
+
d3 &= 8191;
|
|
3295
|
+
let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;
|
|
3296
|
+
c = d4 >>> 13;
|
|
3297
|
+
d4 &= 8191;
|
|
3298
|
+
d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) + h9 * (5 * r5);
|
|
3299
|
+
c += d4 >>> 13;
|
|
3300
|
+
d4 &= 8191;
|
|
3301
|
+
let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;
|
|
3302
|
+
c = d5 >>> 13;
|
|
3303
|
+
d5 &= 8191;
|
|
3304
|
+
d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) + h9 * (5 * r6);
|
|
3305
|
+
c += d5 >>> 13;
|
|
3306
|
+
d5 &= 8191;
|
|
3307
|
+
let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;
|
|
3308
|
+
c = d6 >>> 13;
|
|
3309
|
+
d6 &= 8191;
|
|
3310
|
+
d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);
|
|
3311
|
+
c += d6 >>> 13;
|
|
3312
|
+
d6 &= 8191;
|
|
3313
|
+
let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;
|
|
3314
|
+
c = d7 >>> 13;
|
|
3315
|
+
d7 &= 8191;
|
|
3316
|
+
d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);
|
|
3317
|
+
c += d7 >>> 13;
|
|
3318
|
+
d7 &= 8191;
|
|
3319
|
+
let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;
|
|
3320
|
+
c = d8 >>> 13;
|
|
3321
|
+
d8 &= 8191;
|
|
3322
|
+
d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);
|
|
3323
|
+
c += d8 >>> 13;
|
|
3324
|
+
d8 &= 8191;
|
|
3325
|
+
let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;
|
|
3326
|
+
c = d9 >>> 13;
|
|
3327
|
+
d9 &= 8191;
|
|
3328
|
+
d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;
|
|
3329
|
+
c += d9 >>> 13;
|
|
3330
|
+
d9 &= 8191;
|
|
3331
|
+
c = (c << 2) + c | 0;
|
|
3332
|
+
c = c + d0 | 0;
|
|
3333
|
+
d0 = c & 8191;
|
|
3334
|
+
c = c >>> 13;
|
|
3335
|
+
d1 += c;
|
|
3336
|
+
h[0] = d0;
|
|
3337
|
+
h[1] = d1;
|
|
3338
|
+
h[2] = d2;
|
|
3339
|
+
h[3] = d3;
|
|
3340
|
+
h[4] = d4;
|
|
3341
|
+
h[5] = d5;
|
|
3342
|
+
h[6] = d6;
|
|
3343
|
+
h[7] = d7;
|
|
3344
|
+
h[8] = d8;
|
|
3345
|
+
h[9] = d9;
|
|
3346
|
+
}
|
|
3347
|
+
finalize() {
|
|
3348
|
+
const { h, pad } = this;
|
|
3349
|
+
const g = new Uint16Array(10);
|
|
3350
|
+
let c = h[1] >>> 13;
|
|
3351
|
+
h[1] &= 8191;
|
|
3352
|
+
for (let i = 2; i < 10; i++) {
|
|
3353
|
+
h[i] += c;
|
|
3354
|
+
c = h[i] >>> 13;
|
|
3355
|
+
h[i] &= 8191;
|
|
3356
|
+
}
|
|
3357
|
+
h[0] += c * 5;
|
|
3358
|
+
c = h[0] >>> 13;
|
|
3359
|
+
h[0] &= 8191;
|
|
3360
|
+
h[1] += c;
|
|
3361
|
+
c = h[1] >>> 13;
|
|
3362
|
+
h[1] &= 8191;
|
|
3363
|
+
h[2] += c;
|
|
3364
|
+
g[0] = h[0] + 5;
|
|
3365
|
+
c = g[0] >>> 13;
|
|
3366
|
+
g[0] &= 8191;
|
|
3367
|
+
for (let i = 1; i < 10; i++) {
|
|
3368
|
+
g[i] = h[i] + c;
|
|
3369
|
+
c = g[i] >>> 13;
|
|
3370
|
+
g[i] &= 8191;
|
|
3371
|
+
}
|
|
3372
|
+
g[9] -= 1 << 13;
|
|
3373
|
+
let mask = (c ^ 1) - 1;
|
|
3374
|
+
for (let i = 0; i < 10; i++)
|
|
3375
|
+
g[i] &= mask;
|
|
3376
|
+
mask = ~mask;
|
|
3377
|
+
for (let i = 0; i < 10; i++)
|
|
3378
|
+
h[i] = h[i] & mask | g[i];
|
|
3379
|
+
h[0] = (h[0] | h[1] << 13) & 65535;
|
|
3380
|
+
h[1] = (h[1] >>> 3 | h[2] << 10) & 65535;
|
|
3381
|
+
h[2] = (h[2] >>> 6 | h[3] << 7) & 65535;
|
|
3382
|
+
h[3] = (h[3] >>> 9 | h[4] << 4) & 65535;
|
|
3383
|
+
h[4] = (h[4] >>> 12 | h[5] << 1 | h[6] << 14) & 65535;
|
|
3384
|
+
h[5] = (h[6] >>> 2 | h[7] << 11) & 65535;
|
|
3385
|
+
h[6] = (h[7] >>> 5 | h[8] << 8) & 65535;
|
|
3386
|
+
h[7] = (h[8] >>> 8 | h[9] << 5) & 65535;
|
|
3387
|
+
let f = h[0] + pad[0];
|
|
3388
|
+
h[0] = f & 65535;
|
|
3389
|
+
for (let i = 1; i < 8; i++) {
|
|
3390
|
+
f = (h[i] + pad[i] | 0) + (f >>> 16) | 0;
|
|
3391
|
+
h[i] = f & 65535;
|
|
3392
|
+
}
|
|
3393
|
+
clean2(g);
|
|
3394
|
+
}
|
|
3395
|
+
update(data) {
|
|
3396
|
+
aexists2(this);
|
|
3397
|
+
abytes3(data);
|
|
3398
|
+
data = copyBytes2(data);
|
|
3399
|
+
const { buffer, blockLen } = this;
|
|
3400
|
+
const len = data.length;
|
|
3401
|
+
for (let pos = 0; pos < len; ) {
|
|
3402
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
3403
|
+
if (take === blockLen) {
|
|
3404
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
3405
|
+
this.process(data, pos);
|
|
3406
|
+
continue;
|
|
3407
|
+
}
|
|
3408
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
3409
|
+
this.pos += take;
|
|
3410
|
+
pos += take;
|
|
3411
|
+
if (this.pos === blockLen) {
|
|
3412
|
+
this.process(buffer, 0, false);
|
|
3413
|
+
this.pos = 0;
|
|
3414
|
+
}
|
|
3415
|
+
}
|
|
3416
|
+
return this;
|
|
3417
|
+
}
|
|
3418
|
+
destroy() {
|
|
3419
|
+
this.destroyed = true;
|
|
3420
|
+
clean2(this.h, this.r, this.buffer, this.pad);
|
|
3421
|
+
}
|
|
3422
|
+
digestInto(out) {
|
|
3423
|
+
aexists2(this);
|
|
3424
|
+
aoutput2(out, this);
|
|
3425
|
+
this.finished = true;
|
|
3426
|
+
const { buffer, h } = this;
|
|
3427
|
+
let { pos } = this;
|
|
3428
|
+
if (pos) {
|
|
3429
|
+
buffer[pos++] = 1;
|
|
3430
|
+
for (; pos < 16; pos++)
|
|
3431
|
+
buffer[pos] = 0;
|
|
3432
|
+
this.process(buffer, 0, true);
|
|
3433
|
+
}
|
|
3434
|
+
this.finalize();
|
|
3435
|
+
let opos = 0;
|
|
3436
|
+
for (let i = 0; i < 8; i++) {
|
|
3437
|
+
out[opos++] = h[i] >>> 0;
|
|
3438
|
+
out[opos++] = h[i] >>> 8;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
digest() {
|
|
3442
|
+
const { buffer, outputLen } = this;
|
|
3443
|
+
this.digestInto(buffer);
|
|
3444
|
+
const res = buffer.slice(0, outputLen);
|
|
3445
|
+
this.destroy();
|
|
3446
|
+
return res;
|
|
3447
|
+
}
|
|
3448
|
+
};
|
|
3449
|
+
var poly1305 = /* @__PURE__ */ wrapMacConstructor(32, (key) => new Poly1305(key));
|
|
3450
|
+
|
|
3451
|
+
// ../../node_modules/@noble/ciphers/chacha.js
|
|
3452
|
+
function chachaCore(s, k, n, out, cnt, rounds = 20) {
|
|
3453
|
+
let y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2];
|
|
3454
|
+
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
|
3455
|
+
for (let r = 0; r < rounds; r += 2) {
|
|
3456
|
+
x00 = x00 + x04 | 0;
|
|
3457
|
+
x12 = rotl(x12 ^ x00, 16);
|
|
3458
|
+
x08 = x08 + x12 | 0;
|
|
3459
|
+
x04 = rotl(x04 ^ x08, 12);
|
|
3460
|
+
x00 = x00 + x04 | 0;
|
|
3461
|
+
x12 = rotl(x12 ^ x00, 8);
|
|
3462
|
+
x08 = x08 + x12 | 0;
|
|
3463
|
+
x04 = rotl(x04 ^ x08, 7);
|
|
3464
|
+
x01 = x01 + x05 | 0;
|
|
3465
|
+
x13 = rotl(x13 ^ x01, 16);
|
|
3466
|
+
x09 = x09 + x13 | 0;
|
|
3467
|
+
x05 = rotl(x05 ^ x09, 12);
|
|
3468
|
+
x01 = x01 + x05 | 0;
|
|
3469
|
+
x13 = rotl(x13 ^ x01, 8);
|
|
3470
|
+
x09 = x09 + x13 | 0;
|
|
3471
|
+
x05 = rotl(x05 ^ x09, 7);
|
|
3472
|
+
x02 = x02 + x06 | 0;
|
|
3473
|
+
x14 = rotl(x14 ^ x02, 16);
|
|
3474
|
+
x10 = x10 + x14 | 0;
|
|
3475
|
+
x06 = rotl(x06 ^ x10, 12);
|
|
3476
|
+
x02 = x02 + x06 | 0;
|
|
3477
|
+
x14 = rotl(x14 ^ x02, 8);
|
|
3478
|
+
x10 = x10 + x14 | 0;
|
|
3479
|
+
x06 = rotl(x06 ^ x10, 7);
|
|
3480
|
+
x03 = x03 + x07 | 0;
|
|
3481
|
+
x15 = rotl(x15 ^ x03, 16);
|
|
3482
|
+
x11 = x11 + x15 | 0;
|
|
3483
|
+
x07 = rotl(x07 ^ x11, 12);
|
|
3484
|
+
x03 = x03 + x07 | 0;
|
|
3485
|
+
x15 = rotl(x15 ^ x03, 8);
|
|
3486
|
+
x11 = x11 + x15 | 0;
|
|
3487
|
+
x07 = rotl(x07 ^ x11, 7);
|
|
3488
|
+
x00 = x00 + x05 | 0;
|
|
3489
|
+
x15 = rotl(x15 ^ x00, 16);
|
|
3490
|
+
x10 = x10 + x15 | 0;
|
|
3491
|
+
x05 = rotl(x05 ^ x10, 12);
|
|
3492
|
+
x00 = x00 + x05 | 0;
|
|
3493
|
+
x15 = rotl(x15 ^ x00, 8);
|
|
3494
|
+
x10 = x10 + x15 | 0;
|
|
3495
|
+
x05 = rotl(x05 ^ x10, 7);
|
|
3496
|
+
x01 = x01 + x06 | 0;
|
|
3497
|
+
x12 = rotl(x12 ^ x01, 16);
|
|
3498
|
+
x11 = x11 + x12 | 0;
|
|
3499
|
+
x06 = rotl(x06 ^ x11, 12);
|
|
3500
|
+
x01 = x01 + x06 | 0;
|
|
3501
|
+
x12 = rotl(x12 ^ x01, 8);
|
|
3502
|
+
x11 = x11 + x12 | 0;
|
|
3503
|
+
x06 = rotl(x06 ^ x11, 7);
|
|
3504
|
+
x02 = x02 + x07 | 0;
|
|
3505
|
+
x13 = rotl(x13 ^ x02, 16);
|
|
3506
|
+
x08 = x08 + x13 | 0;
|
|
3507
|
+
x07 = rotl(x07 ^ x08, 12);
|
|
3508
|
+
x02 = x02 + x07 | 0;
|
|
3509
|
+
x13 = rotl(x13 ^ x02, 8);
|
|
3510
|
+
x08 = x08 + x13 | 0;
|
|
3511
|
+
x07 = rotl(x07 ^ x08, 7);
|
|
3512
|
+
x03 = x03 + x04 | 0;
|
|
3513
|
+
x14 = rotl(x14 ^ x03, 16);
|
|
3514
|
+
x09 = x09 + x14 | 0;
|
|
3515
|
+
x04 = rotl(x04 ^ x09, 12);
|
|
3516
|
+
x03 = x03 + x04 | 0;
|
|
3517
|
+
x14 = rotl(x14 ^ x03, 8);
|
|
3518
|
+
x09 = x09 + x14 | 0;
|
|
3519
|
+
x04 = rotl(x04 ^ x09, 7);
|
|
3520
|
+
}
|
|
3521
|
+
let oi = 0;
|
|
3522
|
+
out[oi++] = y00 + x00 | 0;
|
|
3523
|
+
out[oi++] = y01 + x01 | 0;
|
|
3524
|
+
out[oi++] = y02 + x02 | 0;
|
|
3525
|
+
out[oi++] = y03 + x03 | 0;
|
|
3526
|
+
out[oi++] = y04 + x04 | 0;
|
|
3527
|
+
out[oi++] = y05 + x05 | 0;
|
|
3528
|
+
out[oi++] = y06 + x06 | 0;
|
|
3529
|
+
out[oi++] = y07 + x07 | 0;
|
|
3530
|
+
out[oi++] = y08 + x08 | 0;
|
|
3531
|
+
out[oi++] = y09 + x09 | 0;
|
|
3532
|
+
out[oi++] = y10 + x10 | 0;
|
|
3533
|
+
out[oi++] = y11 + x11 | 0;
|
|
3534
|
+
out[oi++] = y12 + x12 | 0;
|
|
3535
|
+
out[oi++] = y13 + x13 | 0;
|
|
3536
|
+
out[oi++] = y14 + x14 | 0;
|
|
3537
|
+
out[oi++] = y15 + x15 | 0;
|
|
3538
|
+
}
|
|
3539
|
+
function hchacha(s, k, i, out) {
|
|
3540
|
+
let x00 = swap8IfBE2(s[0]), x01 = swap8IfBE2(s[1]), x02 = swap8IfBE2(s[2]), x03 = swap8IfBE2(s[3]), x04 = swap8IfBE2(k[0]), x05 = swap8IfBE2(k[1]), x06 = swap8IfBE2(k[2]), x07 = swap8IfBE2(k[3]), x08 = swap8IfBE2(k[4]), x09 = swap8IfBE2(k[5]), x10 = swap8IfBE2(k[6]), x11 = swap8IfBE2(k[7]), x12 = swap8IfBE2(i[0]), x13 = swap8IfBE2(i[1]), x14 = swap8IfBE2(i[2]), x15 = swap8IfBE2(i[3]);
|
|
3541
|
+
for (let r = 0; r < 20; r += 2) {
|
|
3542
|
+
x00 = x00 + x04 | 0;
|
|
3543
|
+
x12 = rotl(x12 ^ x00, 16);
|
|
3544
|
+
x08 = x08 + x12 | 0;
|
|
3545
|
+
x04 = rotl(x04 ^ x08, 12);
|
|
3546
|
+
x00 = x00 + x04 | 0;
|
|
3547
|
+
x12 = rotl(x12 ^ x00, 8);
|
|
3548
|
+
x08 = x08 + x12 | 0;
|
|
3549
|
+
x04 = rotl(x04 ^ x08, 7);
|
|
3550
|
+
x01 = x01 + x05 | 0;
|
|
3551
|
+
x13 = rotl(x13 ^ x01, 16);
|
|
3552
|
+
x09 = x09 + x13 | 0;
|
|
3553
|
+
x05 = rotl(x05 ^ x09, 12);
|
|
3554
|
+
x01 = x01 + x05 | 0;
|
|
3555
|
+
x13 = rotl(x13 ^ x01, 8);
|
|
3556
|
+
x09 = x09 + x13 | 0;
|
|
3557
|
+
x05 = rotl(x05 ^ x09, 7);
|
|
3558
|
+
x02 = x02 + x06 | 0;
|
|
3559
|
+
x14 = rotl(x14 ^ x02, 16);
|
|
3560
|
+
x10 = x10 + x14 | 0;
|
|
3561
|
+
x06 = rotl(x06 ^ x10, 12);
|
|
3562
|
+
x02 = x02 + x06 | 0;
|
|
3563
|
+
x14 = rotl(x14 ^ x02, 8);
|
|
3564
|
+
x10 = x10 + x14 | 0;
|
|
3565
|
+
x06 = rotl(x06 ^ x10, 7);
|
|
3566
|
+
x03 = x03 + x07 | 0;
|
|
3567
|
+
x15 = rotl(x15 ^ x03, 16);
|
|
3568
|
+
x11 = x11 + x15 | 0;
|
|
3569
|
+
x07 = rotl(x07 ^ x11, 12);
|
|
3570
|
+
x03 = x03 + x07 | 0;
|
|
3571
|
+
x15 = rotl(x15 ^ x03, 8);
|
|
3572
|
+
x11 = x11 + x15 | 0;
|
|
3573
|
+
x07 = rotl(x07 ^ x11, 7);
|
|
3574
|
+
x00 = x00 + x05 | 0;
|
|
3575
|
+
x15 = rotl(x15 ^ x00, 16);
|
|
3576
|
+
x10 = x10 + x15 | 0;
|
|
3577
|
+
x05 = rotl(x05 ^ x10, 12);
|
|
3578
|
+
x00 = x00 + x05 | 0;
|
|
3579
|
+
x15 = rotl(x15 ^ x00, 8);
|
|
3580
|
+
x10 = x10 + x15 | 0;
|
|
3581
|
+
x05 = rotl(x05 ^ x10, 7);
|
|
3582
|
+
x01 = x01 + x06 | 0;
|
|
3583
|
+
x12 = rotl(x12 ^ x01, 16);
|
|
3584
|
+
x11 = x11 + x12 | 0;
|
|
3585
|
+
x06 = rotl(x06 ^ x11, 12);
|
|
3586
|
+
x01 = x01 + x06 | 0;
|
|
3587
|
+
x12 = rotl(x12 ^ x01, 8);
|
|
3588
|
+
x11 = x11 + x12 | 0;
|
|
3589
|
+
x06 = rotl(x06 ^ x11, 7);
|
|
3590
|
+
x02 = x02 + x07 | 0;
|
|
3591
|
+
x13 = rotl(x13 ^ x02, 16);
|
|
3592
|
+
x08 = x08 + x13 | 0;
|
|
3593
|
+
x07 = rotl(x07 ^ x08, 12);
|
|
3594
|
+
x02 = x02 + x07 | 0;
|
|
3595
|
+
x13 = rotl(x13 ^ x02, 8);
|
|
3596
|
+
x08 = x08 + x13 | 0;
|
|
3597
|
+
x07 = rotl(x07 ^ x08, 7);
|
|
3598
|
+
x03 = x03 + x04 | 0;
|
|
3599
|
+
x14 = rotl(x14 ^ x03, 16);
|
|
3600
|
+
x09 = x09 + x14 | 0;
|
|
3601
|
+
x04 = rotl(x04 ^ x09, 12);
|
|
3602
|
+
x03 = x03 + x04 | 0;
|
|
3603
|
+
x14 = rotl(x14 ^ x03, 8);
|
|
3604
|
+
x09 = x09 + x14 | 0;
|
|
3605
|
+
x04 = rotl(x04 ^ x09, 7);
|
|
3606
|
+
}
|
|
3607
|
+
let oi = 0;
|
|
3608
|
+
out[oi++] = x00;
|
|
3609
|
+
out[oi++] = x01;
|
|
3610
|
+
out[oi++] = x02;
|
|
3611
|
+
out[oi++] = x03;
|
|
3612
|
+
out[oi++] = x12;
|
|
3613
|
+
out[oi++] = x13;
|
|
3614
|
+
out[oi++] = x14;
|
|
3615
|
+
out[oi++] = x15;
|
|
3616
|
+
swap32IfBE2(out);
|
|
3617
|
+
}
|
|
3618
|
+
var chacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
|
3619
|
+
counterRight: false,
|
|
3620
|
+
counterLength: 4,
|
|
3621
|
+
allowShortKeys: false
|
|
3622
|
+
});
|
|
3623
|
+
var xchacha20 = /* @__PURE__ */ createCipher(chachaCore, {
|
|
3624
|
+
counterRight: false,
|
|
3625
|
+
counterLength: 8,
|
|
3626
|
+
extendNonceFn: hchacha,
|
|
3627
|
+
allowShortKeys: false
|
|
3628
|
+
});
|
|
3629
|
+
var ZEROS16 = /* @__PURE__ */ new Uint8Array(16);
|
|
3630
|
+
var updatePadded = (h, msg) => {
|
|
3631
|
+
h.update(msg);
|
|
3632
|
+
const leftover = msg.length % 16;
|
|
3633
|
+
if (leftover)
|
|
3634
|
+
h.update(ZEROS16.subarray(leftover));
|
|
3635
|
+
};
|
|
3636
|
+
var ZEROS32 = /* @__PURE__ */ new Uint8Array(32);
|
|
3637
|
+
function computeTag(fn, key, nonce, ciphertext, AAD) {
|
|
3638
|
+
if (AAD !== void 0)
|
|
3639
|
+
abytes3(AAD, void 0, "AAD");
|
|
3640
|
+
const authKey = fn(key, nonce, ZEROS32);
|
|
3641
|
+
const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true);
|
|
3642
|
+
const h = poly1305.create(authKey);
|
|
3643
|
+
if (AAD)
|
|
3644
|
+
updatePadded(h, AAD);
|
|
3645
|
+
updatePadded(h, ciphertext);
|
|
3646
|
+
h.update(lengths);
|
|
3647
|
+
const res = h.digest();
|
|
3648
|
+
clean2(authKey, lengths);
|
|
3649
|
+
return res;
|
|
3650
|
+
}
|
|
3651
|
+
var _poly1305_aead = (xorStream) => (key, nonce, AAD) => {
|
|
3652
|
+
const tagLength = 16;
|
|
3653
|
+
return {
|
|
3654
|
+
encrypt(plaintext, output) {
|
|
3655
|
+
const plength = plaintext.length;
|
|
3656
|
+
output = getOutput(plength + tagLength, output, false);
|
|
3657
|
+
output.set(plaintext);
|
|
3658
|
+
const oPlain = output.subarray(0, -tagLength);
|
|
3659
|
+
xorStream(key, nonce, oPlain, oPlain, 1);
|
|
3660
|
+
const tag = computeTag(xorStream, key, nonce, oPlain, AAD);
|
|
3661
|
+
output.set(tag, plength);
|
|
3662
|
+
clean2(tag);
|
|
3663
|
+
return output;
|
|
3664
|
+
},
|
|
3665
|
+
decrypt(ciphertext, output) {
|
|
3666
|
+
output = getOutput(ciphertext.length - tagLength, output, false);
|
|
3667
|
+
const data = ciphertext.subarray(0, -tagLength);
|
|
3668
|
+
const passedTag = ciphertext.subarray(-tagLength);
|
|
3669
|
+
const tag = computeTag(xorStream, key, nonce, data, AAD);
|
|
3670
|
+
if (!equalBytes2(passedTag, tag)) {
|
|
3671
|
+
clean2(tag);
|
|
3672
|
+
throw new Error("invalid tag");
|
|
3673
|
+
}
|
|
3674
|
+
output.set(ciphertext.subarray(0, -tagLength));
|
|
3675
|
+
xorStream(key, nonce, output, output, 1);
|
|
3676
|
+
clean2(tag);
|
|
3677
|
+
return output;
|
|
3678
|
+
}
|
|
3679
|
+
};
|
|
3680
|
+
};
|
|
3681
|
+
var chacha20poly1305 = /* @__PURE__ */ wrapCipher(
|
|
3682
|
+
{ blockSize: 64, nonceLength: 12, tagLength: 16 },
|
|
3683
|
+
/* @__PURE__ */ _poly1305_aead(chacha20)
|
|
3684
|
+
);
|
|
3685
|
+
var xchacha20poly1305 = /* @__PURE__ */ wrapCipher(
|
|
3686
|
+
{ blockSize: 64, nonceLength: 24, tagLength: 16 },
|
|
3687
|
+
/* @__PURE__ */ _poly1305_aead(xchacha20)
|
|
3688
|
+
);
|
|
3689
|
+
|
|
3690
|
+
// src/crypto/primitives.ts
|
|
3691
|
+
var X25519_KEY_LENGTH = 32;
|
|
3692
|
+
var ED25519_KEY_LENGTH = 32;
|
|
3693
|
+
var ED25519_SIGNATURE_LENGTH = 64;
|
|
3694
|
+
var HASH_LENGTH = 32;
|
|
3695
|
+
var AEAD_KEY_LENGTH = 32;
|
|
3696
|
+
var CHACHA_NONCE_LENGTH = 12;
|
|
3697
|
+
var XCHACHA_NONCE_LENGTH = 24;
|
|
3698
|
+
var AEAD_TAG_LENGTH = 16;
|
|
3699
|
+
function assertLength(bytes, expected, label) {
|
|
3700
|
+
if (bytes.length !== expected) {
|
|
3701
|
+
throw new Error(`${label} must be ${expected} bytes, got ${bytes.length}`);
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
function randomBytes4(length) {
|
|
3705
|
+
return randomBytes(length);
|
|
3706
|
+
}
|
|
3707
|
+
function generateX25519KeyPair() {
|
|
3708
|
+
return x25519.keygen();
|
|
3709
|
+
}
|
|
3710
|
+
function x25519PublicKeyFrom(secretKey) {
|
|
3711
|
+
assertLength(secretKey, X25519_KEY_LENGTH, "x25519 secret key");
|
|
3712
|
+
return x25519.getPublicKey(secretKey);
|
|
3713
|
+
}
|
|
3714
|
+
function x25519SharedSecret(secretKey, publicKey) {
|
|
3715
|
+
assertLength(secretKey, X25519_KEY_LENGTH, "x25519 secret key");
|
|
3716
|
+
assertLength(publicKey, X25519_KEY_LENGTH, "x25519 public key");
|
|
3717
|
+
return x25519.getSharedSecret(secretKey, publicKey);
|
|
3718
|
+
}
|
|
3719
|
+
function generateEd25519KeyPair() {
|
|
3720
|
+
return ed25519.keygen();
|
|
3721
|
+
}
|
|
3722
|
+
function ed25519Sign(message, secretKey) {
|
|
3723
|
+
assertLength(secretKey, ED25519_KEY_LENGTH, "ed25519 secret key");
|
|
3724
|
+
return ed25519.sign(message, secretKey);
|
|
3725
|
+
}
|
|
3726
|
+
function ed25519Verify(signature, message, publicKey) {
|
|
3727
|
+
assertLength(signature, ED25519_SIGNATURE_LENGTH, "ed25519 signature");
|
|
3728
|
+
assertLength(publicKey, ED25519_KEY_LENGTH, "ed25519 public key");
|
|
3729
|
+
return ed25519.verify(signature, message, publicKey);
|
|
3730
|
+
}
|
|
3731
|
+
function hashBlake2s(data) {
|
|
3732
|
+
return blake2s(data);
|
|
3733
|
+
}
|
|
3734
|
+
function noiseHkdf(chainingKey, inputKeyMaterial, numOutputs) {
|
|
3735
|
+
const output = hkdf(blake2s, inputKeyMaterial, chainingKey, new Uint8Array(0), numOutputs * HASH_LENGTH);
|
|
3736
|
+
const chunks = [];
|
|
3737
|
+
for (let i = 0; i < numOutputs; i++) {
|
|
3738
|
+
chunks.push(output.subarray(i * HASH_LENGTH, (i + 1) * HASH_LENGTH));
|
|
3739
|
+
}
|
|
3740
|
+
return chunks;
|
|
3741
|
+
}
|
|
3742
|
+
function deriveLabeledKey(chainingKey, label, length) {
|
|
3743
|
+
return hkdf(blake2s, new Uint8Array(0), chainingKey, new TextEncoder().encode(label), length);
|
|
3744
|
+
}
|
|
3745
|
+
function chachaNonce(counter) {
|
|
3746
|
+
const nonce = new Uint8Array(CHACHA_NONCE_LENGTH);
|
|
3747
|
+
const view = new DataView(nonce.buffer);
|
|
3748
|
+
view.setBigUint64(4, counter, true);
|
|
3749
|
+
return nonce;
|
|
3750
|
+
}
|
|
3751
|
+
function aeadEncrypt(key, counter, associatedData, plaintext) {
|
|
3752
|
+
assertLength(key, AEAD_KEY_LENGTH, "AEAD key");
|
|
3753
|
+
const cipher = chacha20poly1305(key, chachaNonce(counter), associatedData);
|
|
3754
|
+
return cipher.encrypt(plaintext);
|
|
3755
|
+
}
|
|
3756
|
+
function aeadDecrypt(key, counter, associatedData, ciphertext) {
|
|
3757
|
+
assertLength(key, AEAD_KEY_LENGTH, "AEAD key");
|
|
3758
|
+
const cipher = chacha20poly1305(key, chachaNonce(counter), associatedData);
|
|
3759
|
+
return cipher.decrypt(ciphertext);
|
|
3760
|
+
}
|
|
3761
|
+
function xaeadEncrypt(key, nonce, associatedData, plaintext) {
|
|
3762
|
+
assertLength(key, AEAD_KEY_LENGTH, "XAEAD key");
|
|
3763
|
+
assertLength(nonce, XCHACHA_NONCE_LENGTH, "XAEAD nonce");
|
|
3764
|
+
const cipher = xchacha20poly1305(key, nonce, associatedData);
|
|
3765
|
+
return cipher.encrypt(plaintext);
|
|
3766
|
+
}
|
|
3767
|
+
function xaeadDecrypt(key, nonce, associatedData, ciphertext) {
|
|
3768
|
+
assertLength(key, AEAD_KEY_LENGTH, "XAEAD key");
|
|
3769
|
+
assertLength(nonce, XCHACHA_NONCE_LENGTH, "XAEAD nonce");
|
|
3770
|
+
const cipher = xchacha20poly1305(key, nonce, associatedData);
|
|
3771
|
+
return cipher.decrypt(ciphertext);
|
|
3772
|
+
}
|
|
3773
|
+
function concatBytes4(...arrays) {
|
|
3774
|
+
const total = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
3775
|
+
const result = new Uint8Array(total);
|
|
3776
|
+
let offset = 0;
|
|
3777
|
+
for (const arr of arrays) {
|
|
3778
|
+
result.set(arr, offset);
|
|
3779
|
+
offset += arr.length;
|
|
3780
|
+
}
|
|
3781
|
+
return result;
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
// src/crypto/noise/cipher-state.ts
|
|
3785
|
+
var MAX_NONCE = 0xffffffffffffffffn;
|
|
3786
|
+
var CipherState = class {
|
|
3787
|
+
key = null;
|
|
3788
|
+
nonce = 0n;
|
|
3789
|
+
initializeKey(key) {
|
|
3790
|
+
this.key = key;
|
|
3791
|
+
this.nonce = 0n;
|
|
3792
|
+
}
|
|
3793
|
+
hasKey() {
|
|
3794
|
+
return this.key !== null;
|
|
3795
|
+
}
|
|
3796
|
+
encryptWithAd(associatedData, plaintext) {
|
|
3797
|
+
if (this.key === null) return plaintext;
|
|
3798
|
+
if (this.nonce >= MAX_NONCE) throw new Error("Noise CipherState nonce space exhausted");
|
|
3799
|
+
const ciphertext = aeadEncrypt(this.key, this.nonce, associatedData, plaintext);
|
|
3800
|
+
this.nonce += 1n;
|
|
3801
|
+
return ciphertext;
|
|
3802
|
+
}
|
|
3803
|
+
/** Nonce is only advanced on a SUCCESSFUL decrypt; aeadDecrypt throws on tag failure. */
|
|
3804
|
+
decryptWithAd(associatedData, ciphertext) {
|
|
3805
|
+
if (this.key === null) return ciphertext;
|
|
3806
|
+
if (this.nonce >= MAX_NONCE) throw new Error("Noise CipherState nonce space exhausted");
|
|
3807
|
+
const plaintext = aeadDecrypt(this.key, this.nonce, associatedData, ciphertext);
|
|
3808
|
+
this.nonce += 1n;
|
|
3809
|
+
return plaintext;
|
|
3810
|
+
}
|
|
3811
|
+
};
|
|
3812
|
+
|
|
3813
|
+
// src/crypto/noise/symmetric-state.ts
|
|
3814
|
+
var SymmetricState = class {
|
|
3815
|
+
cipherState = new CipherState();
|
|
3816
|
+
chainingKey;
|
|
3817
|
+
hash;
|
|
3818
|
+
constructor(protocolName) {
|
|
3819
|
+
if (protocolName.length <= HASH_LENGTH) {
|
|
3820
|
+
this.hash = concatBytes4(protocolName, new Uint8Array(HASH_LENGTH - protocolName.length));
|
|
3821
|
+
} else {
|
|
3822
|
+
this.hash = hashBlake2s(protocolName);
|
|
3823
|
+
}
|
|
3824
|
+
this.chainingKey = this.hash;
|
|
3825
|
+
this.cipherState.initializeKey(null);
|
|
3826
|
+
}
|
|
3827
|
+
mixKey(inputKeyMaterial) {
|
|
3828
|
+
const [nextChainingKey, tempKey] = noiseHkdf(this.chainingKey, inputKeyMaterial, 2);
|
|
3829
|
+
this.chainingKey = nextChainingKey;
|
|
3830
|
+
this.cipherState.initializeKey(tempKey);
|
|
3831
|
+
}
|
|
3832
|
+
mixHash(data) {
|
|
3833
|
+
this.hash = hashBlake2s(concatBytes4(this.hash, data));
|
|
3834
|
+
}
|
|
3835
|
+
/** Processes a "psk" token: MixKeyAndHash(psk) per Noise section 9. */
|
|
3836
|
+
mixKeyAndHash(inputKeyMaterial) {
|
|
3837
|
+
const [nextChainingKey, tempHash, tempKey] = noiseHkdf(this.chainingKey, inputKeyMaterial, 3);
|
|
3838
|
+
this.chainingKey = nextChainingKey;
|
|
3839
|
+
this.mixHash(tempHash);
|
|
3840
|
+
this.cipherState.initializeKey(tempKey);
|
|
3841
|
+
}
|
|
3842
|
+
getHandshakeHash() {
|
|
3843
|
+
return this.hash;
|
|
3844
|
+
}
|
|
3845
|
+
/**
|
|
3846
|
+
* The raw chaining key, meaningful only after the handshake's message
|
|
3847
|
+
* patterns are exhausted (alongside split()). Exposed so a caller can
|
|
3848
|
+
* derive ADDITIONAL independent key material (e.g. secretstream framing
|
|
3849
|
+
* keys) via its own domain-separated HKDF label - see
|
|
3850
|
+
* crypto/secretstream.ts's deriveTransportKey. This is standard KDF
|
|
3851
|
+
* practice (TLS 1.3's key schedule does the same): reusing one secret
|
|
3852
|
+
* for multiple purposes via distinct labels is safe; Split()'s own
|
|
3853
|
+
* derivation (empty info) and a labeled derivation never collide.
|
|
3854
|
+
*/
|
|
3855
|
+
getChainingKey() {
|
|
3856
|
+
return this.chainingKey;
|
|
3857
|
+
}
|
|
3858
|
+
encryptAndHash(plaintext) {
|
|
3859
|
+
const ciphertext = this.cipherState.encryptWithAd(this.hash, plaintext);
|
|
3860
|
+
this.mixHash(ciphertext);
|
|
3861
|
+
return ciphertext;
|
|
3862
|
+
}
|
|
3863
|
+
decryptAndHash(ciphertext) {
|
|
3864
|
+
const plaintext = this.cipherState.decryptWithAd(this.hash, ciphertext);
|
|
3865
|
+
this.mixHash(ciphertext);
|
|
3866
|
+
return plaintext;
|
|
3867
|
+
}
|
|
3868
|
+
hasKey() {
|
|
3869
|
+
return this.cipherState.hasKey();
|
|
3870
|
+
}
|
|
3871
|
+
/** Only valid once every message pattern has been processed. */
|
|
3872
|
+
split() {
|
|
3873
|
+
const [tempKey1, tempKey2] = noiseHkdf(this.chainingKey, new Uint8Array(0), 2);
|
|
3874
|
+
const c1 = new CipherState();
|
|
3875
|
+
const c2 = new CipherState();
|
|
3876
|
+
c1.initializeKey(tempKey1);
|
|
3877
|
+
c2.initializeKey(tempKey2);
|
|
3878
|
+
return [c1, c2];
|
|
3879
|
+
}
|
|
3880
|
+
};
|
|
3881
|
+
|
|
3882
|
+
// src/crypto/noise/handshake-state.ts
|
|
3883
|
+
var HandshakeState = class {
|
|
3884
|
+
symmetricState;
|
|
3885
|
+
pattern;
|
|
3886
|
+
initiator;
|
|
3887
|
+
generateEphemeral;
|
|
3888
|
+
psk;
|
|
3889
|
+
s;
|
|
3890
|
+
e;
|
|
3891
|
+
rs;
|
|
3892
|
+
re;
|
|
3893
|
+
messageIndex = 0;
|
|
3894
|
+
constructor(options) {
|
|
3895
|
+
this.pattern = options.pattern;
|
|
3896
|
+
this.initiator = options.initiator;
|
|
3897
|
+
this.s = options.s;
|
|
3898
|
+
this.e = options.e;
|
|
3899
|
+
this.rs = options.rs;
|
|
3900
|
+
this.re = options.re;
|
|
3901
|
+
this.psk = options.psk;
|
|
3902
|
+
this.generateEphemeral = options.generateEphemeral ?? generateX25519KeyPair;
|
|
3903
|
+
const protocolName = new TextEncoder().encode(`Noise_${this.pattern.name}_25519_ChaChaPoly_BLAKE2s`);
|
|
3904
|
+
this.symmetricState = new SymmetricState(protocolName);
|
|
3905
|
+
this.symmetricState.mixHash(options.prologue);
|
|
3906
|
+
for (const token of this.pattern.initiatorPreMessage) {
|
|
3907
|
+
this.symmetricState.mixHash(this.resolvePreMessageKey(token, true));
|
|
3908
|
+
}
|
|
3909
|
+
for (const token of this.pattern.responderPreMessage) {
|
|
3910
|
+
this.symmetricState.mixHash(this.resolvePreMessageKey(token, false));
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
resolvePreMessageKey(token, isInitiatorSide) {
|
|
3914
|
+
if (token !== "s") throw new Error(`Unsupported pre-message token: ${token}`);
|
|
3915
|
+
const isLocalSide = isInitiatorSide === this.initiator;
|
|
3916
|
+
if (isLocalSide) {
|
|
3917
|
+
if (!this.s) throw new Error("Local static key required by this pattern but not provided");
|
|
3918
|
+
return this.s.publicKey;
|
|
3919
|
+
}
|
|
3920
|
+
if (!this.rs) throw new Error("Remote static key required by this pattern but not provided");
|
|
3921
|
+
return this.rs;
|
|
3922
|
+
}
|
|
3923
|
+
requireLocalKeyPair(which) {
|
|
3924
|
+
const keyPair = which === "e" ? this.e : this.s;
|
|
3925
|
+
if (!keyPair) throw new Error(`Local "${which}" key required for this token but not available`);
|
|
3926
|
+
return keyPair;
|
|
3927
|
+
}
|
|
3928
|
+
requireRemoteKey(which) {
|
|
3929
|
+
const publicKey = which === "re" ? this.re : this.rs;
|
|
3930
|
+
if (!publicKey) throw new Error(`Remote "${which}" key required for this token but not available`);
|
|
3931
|
+
return publicKey;
|
|
3932
|
+
}
|
|
3933
|
+
requirePsk() {
|
|
3934
|
+
if (!this.psk) throw new Error("PSK required by this pattern but not provided");
|
|
3935
|
+
return this.psk;
|
|
3936
|
+
}
|
|
3937
|
+
dh(local, remotePublicKey) {
|
|
3938
|
+
return x25519SharedSecret(local.secretKey, remotePublicKey);
|
|
3939
|
+
}
|
|
3940
|
+
mixDhToken(token) {
|
|
3941
|
+
switch (token) {
|
|
3942
|
+
case "ee":
|
|
3943
|
+
this.symmetricState.mixKey(this.dh(this.requireLocalKeyPair("e"), this.requireRemoteKey("re")));
|
|
3944
|
+
return;
|
|
3945
|
+
case "es":
|
|
3946
|
+
this.symmetricState.mixKey(
|
|
3947
|
+
this.initiator ? this.dh(this.requireLocalKeyPair("e"), this.requireRemoteKey("rs")) : this.dh(this.requireLocalKeyPair("s"), this.requireRemoteKey("re"))
|
|
3948
|
+
);
|
|
3949
|
+
return;
|
|
3950
|
+
case "se":
|
|
3951
|
+
this.symmetricState.mixKey(
|
|
3952
|
+
this.initiator ? this.dh(this.requireLocalKeyPair("s"), this.requireRemoteKey("re")) : this.dh(this.requireLocalKeyPair("e"), this.requireRemoteKey("rs"))
|
|
3953
|
+
);
|
|
3954
|
+
return;
|
|
3955
|
+
case "ss":
|
|
3956
|
+
this.symmetricState.mixKey(this.dh(this.requireLocalKeyPair("s"), this.requireRemoteKey("rs")));
|
|
3957
|
+
return;
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
nextTokens() {
|
|
3961
|
+
const tokens = this.pattern.messages[this.messageIndex];
|
|
3962
|
+
if (!tokens) throw new Error("No more messages remain in this handshake pattern");
|
|
3963
|
+
this.messageIndex += 1;
|
|
3964
|
+
return tokens;
|
|
3965
|
+
}
|
|
3966
|
+
maybeSplit() {
|
|
3967
|
+
return this.messageIndex >= this.pattern.messages.length ? this.symmetricState.split() : void 0;
|
|
3968
|
+
}
|
|
3969
|
+
writeMessage(payload) {
|
|
3970
|
+
const tokens = this.nextTokens();
|
|
3971
|
+
const buffers = [];
|
|
3972
|
+
for (const token of tokens) {
|
|
3973
|
+
switch (token) {
|
|
3974
|
+
case "e": {
|
|
3975
|
+
this.e = this.generateEphemeral();
|
|
3976
|
+
buffers.push(this.e.publicKey);
|
|
3977
|
+
this.symmetricState.mixHash(this.e.publicKey);
|
|
3978
|
+
if (this.pattern.usesPsk) this.symmetricState.mixKey(this.e.publicKey);
|
|
3979
|
+
break;
|
|
3980
|
+
}
|
|
3981
|
+
case "s": {
|
|
3982
|
+
buffers.push(this.symmetricState.encryptAndHash(this.requireLocalKeyPair("s").publicKey));
|
|
3983
|
+
break;
|
|
3984
|
+
}
|
|
3985
|
+
case "psk":
|
|
3986
|
+
this.symmetricState.mixKeyAndHash(this.requirePsk());
|
|
3987
|
+
break;
|
|
3988
|
+
default:
|
|
3989
|
+
this.mixDhToken(token);
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3992
|
+
buffers.push(this.symmetricState.encryptAndHash(payload));
|
|
3993
|
+
return { message: concatBytes4(...buffers), split: this.maybeSplit() };
|
|
3994
|
+
}
|
|
3995
|
+
readMessage(message) {
|
|
3996
|
+
const tokens = this.nextTokens();
|
|
3997
|
+
let offset = 0;
|
|
3998
|
+
for (const token of tokens) {
|
|
3999
|
+
switch (token) {
|
|
4000
|
+
case "e": {
|
|
4001
|
+
this.re = message.subarray(offset, offset + X25519_KEY_LENGTH);
|
|
4002
|
+
offset += X25519_KEY_LENGTH;
|
|
4003
|
+
this.symmetricState.mixHash(this.re);
|
|
4004
|
+
if (this.pattern.usesPsk) this.symmetricState.mixKey(this.re);
|
|
4005
|
+
break;
|
|
4006
|
+
}
|
|
4007
|
+
case "s": {
|
|
4008
|
+
const fieldLength = this.symmetricState.hasKey() ? X25519_KEY_LENGTH + AEAD_TAG_LENGTH : X25519_KEY_LENGTH;
|
|
4009
|
+
const field = message.subarray(offset, offset + fieldLength);
|
|
4010
|
+
offset += fieldLength;
|
|
4011
|
+
this.rs = this.symmetricState.decryptAndHash(field);
|
|
4012
|
+
break;
|
|
4013
|
+
}
|
|
4014
|
+
case "psk":
|
|
4015
|
+
this.symmetricState.mixKeyAndHash(this.requirePsk());
|
|
4016
|
+
break;
|
|
4017
|
+
default:
|
|
4018
|
+
this.mixDhToken(token);
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
const payload = this.symmetricState.decryptAndHash(message.subarray(offset));
|
|
4022
|
+
return { payload, split: this.maybeSplit() };
|
|
4023
|
+
}
|
|
4024
|
+
getHandshakeHash() {
|
|
4025
|
+
return this.symmetricState.getHandshakeHash();
|
|
4026
|
+
}
|
|
4027
|
+
/** See SymmetricState.getChainingKey(): only meaningful once split() has occurred. */
|
|
4028
|
+
getChainingKey() {
|
|
4029
|
+
return this.symmetricState.getChainingKey();
|
|
4030
|
+
}
|
|
4031
|
+
/** The remote static public key, once learned (pre-shared or received via an "s" token). */
|
|
4032
|
+
getRemoteStaticKey() {
|
|
4033
|
+
return this.rs;
|
|
4034
|
+
}
|
|
4035
|
+
};
|
|
4036
|
+
|
|
4037
|
+
// src/crypto/noise/patterns.ts
|
|
4038
|
+
var KK_PATTERN = {
|
|
4039
|
+
name: "KK",
|
|
4040
|
+
initiatorPreMessage: ["s"],
|
|
4041
|
+
responderPreMessage: ["s"],
|
|
4042
|
+
messages: [
|
|
4043
|
+
["e", "es", "ss"],
|
|
4044
|
+
["e", "ee", "se"]
|
|
4045
|
+
],
|
|
4046
|
+
usesPsk: false
|
|
4047
|
+
};
|
|
4048
|
+
var IKPSK0_PATTERN = {
|
|
4049
|
+
name: "IKpsk0",
|
|
4050
|
+
initiatorPreMessage: [],
|
|
4051
|
+
responderPreMessage: ["s"],
|
|
4052
|
+
messages: [
|
|
4053
|
+
["psk", "e", "es", "s", "ss"],
|
|
4054
|
+
["e", "ee", "se"]
|
|
4055
|
+
],
|
|
4056
|
+
usesPsk: true
|
|
4057
|
+
};
|
|
4058
|
+
|
|
4059
|
+
// src/crypto/noise/kk.ts
|
|
4060
|
+
function createKKHandshake(options) {
|
|
4061
|
+
return new HandshakeState({
|
|
4062
|
+
pattern: KK_PATTERN,
|
|
4063
|
+
initiator: options.initiator,
|
|
4064
|
+
prologue: encodeProtocolVersion(options.protocolVersion),
|
|
4065
|
+
s: options.localStatic,
|
|
4066
|
+
rs: options.remoteStatic
|
|
4067
|
+
});
|
|
4068
|
+
}
|
|
4069
|
+
|
|
4070
|
+
// src/crypto/pairing-handshake.ts
|
|
4071
|
+
function createPairingInitiatorHandshake(options) {
|
|
4072
|
+
return new HandshakeState({
|
|
4073
|
+
pattern: IKPSK0_PATTERN,
|
|
4074
|
+
initiator: true,
|
|
4075
|
+
prologue: encodeProtocolVersion(options.protocolVersion),
|
|
4076
|
+
s: options.localStatic,
|
|
4077
|
+
rs: options.remoteStatic,
|
|
4078
|
+
psk: options.pairingToken
|
|
4079
|
+
});
|
|
4080
|
+
}
|
|
4081
|
+
function createPairingResponderHandshake(options) {
|
|
4082
|
+
return new HandshakeState({
|
|
4083
|
+
pattern: IKPSK0_PATTERN,
|
|
4084
|
+
initiator: false,
|
|
4085
|
+
prologue: encodeProtocolVersion(options.protocolVersion),
|
|
4086
|
+
s: options.localStatic,
|
|
4087
|
+
psk: options.pairingToken
|
|
4088
|
+
});
|
|
4089
|
+
}
|
|
4090
|
+
|
|
4091
|
+
// src/crypto/secretstream.ts
|
|
4092
|
+
var FrameTag = {
|
|
4093
|
+
Message: 0,
|
|
4094
|
+
Rekey: 1,
|
|
4095
|
+
Final: 2
|
|
4096
|
+
};
|
|
4097
|
+
var NONCE_COUNTER_OFFSET = XCHACHA_NONCE_LENGTH - 8;
|
|
4098
|
+
var MAX_COUNTER2 = 0xffffffffffffffffn;
|
|
4099
|
+
var SecretstreamState = class {
|
|
4100
|
+
key;
|
|
4101
|
+
nonceHeader;
|
|
4102
|
+
counter = 0n;
|
|
4103
|
+
constructor(key, nonceHeader) {
|
|
4104
|
+
if (nonceHeader.length !== XCHACHA_NONCE_LENGTH) {
|
|
4105
|
+
throw new Error(`Secretstream nonce header must be ${XCHACHA_NONCE_LENGTH} bytes, got ${nonceHeader.length}`);
|
|
4106
|
+
}
|
|
4107
|
+
this.key = key;
|
|
4108
|
+
this.nonceHeader = nonceHeader;
|
|
4109
|
+
}
|
|
4110
|
+
nonceForCounter(counter) {
|
|
4111
|
+
const nonce = this.nonceHeader.slice();
|
|
4112
|
+
const view = new DataView(nonce.buffer, nonce.byteOffset, nonce.byteLength);
|
|
4113
|
+
const suffix = view.getBigUint64(NONCE_COUNTER_OFFSET, true);
|
|
4114
|
+
view.setBigUint64(NONCE_COUNTER_OFFSET, suffix ^ counter, true);
|
|
4115
|
+
return nonce;
|
|
4116
|
+
}
|
|
4117
|
+
/** Encrypts one frame and advances this direction's counter. */
|
|
4118
|
+
seal(plaintext, tag = FrameTag.Message) {
|
|
4119
|
+
if (this.counter >= MAX_COUNTER2) throw new Error("Secretstream counter space exhausted; re-handshake required");
|
|
4120
|
+
const associatedData = Uint8Array.of(tag);
|
|
4121
|
+
const ciphertext = xaeadEncrypt(this.key, this.nonceForCounter(this.counter), associatedData, plaintext);
|
|
4122
|
+
this.counter += 1n;
|
|
4123
|
+
return concatBytes4(associatedData, ciphertext);
|
|
4124
|
+
}
|
|
4125
|
+
/**
|
|
4126
|
+
* Decrypts one frame and advances this direction's counter. Throws if
|
|
4127
|
+
* the frame does not authenticate against the counter this instance
|
|
4128
|
+
* currently expects - which is exactly what happens if a frame was
|
|
4129
|
+
* replayed, reordered, or the stream was truncated and resumed wrong.
|
|
4130
|
+
*/
|
|
4131
|
+
open(frame) {
|
|
4132
|
+
if (frame.length < 1) throw new Error("Secretstream frame is too short to contain a tag byte");
|
|
4133
|
+
if (this.counter >= MAX_COUNTER2) throw new Error("Secretstream counter space exhausted; re-handshake required");
|
|
4134
|
+
const tag = frame[0];
|
|
4135
|
+
const associatedData = frame.subarray(0, 1);
|
|
4136
|
+
const ciphertext = frame.subarray(1);
|
|
4137
|
+
const plaintext = xaeadDecrypt(this.key, this.nonceForCounter(this.counter), associatedData, ciphertext);
|
|
4138
|
+
this.counter += 1n;
|
|
4139
|
+
return { tag, plaintext };
|
|
4140
|
+
}
|
|
4141
|
+
/** Rotates this direction's key without a full Noise re-handshake, matching libsodium's REKEY tag. */
|
|
4142
|
+
rekey() {
|
|
4143
|
+
this.key = deriveLabeledKey(this.key, "kangentic-secretstream-rekey", this.key.length);
|
|
4144
|
+
}
|
|
4145
|
+
};
|
|
4146
|
+
function deriveSecretstreamPair(chainingKey, isInitiator) {
|
|
4147
|
+
const initiatorKey = deriveLabeledKey(chainingKey, "kangentic-secretstream-key-initiator", 32);
|
|
4148
|
+
const responderKey = deriveLabeledKey(chainingKey, "kangentic-secretstream-key-responder", 32);
|
|
4149
|
+
const initiatorNonceHeader = deriveLabeledKey(chainingKey, "kangentic-secretstream-nonce-initiator", XCHACHA_NONCE_LENGTH);
|
|
4150
|
+
const responderNonceHeader = deriveLabeledKey(chainingKey, "kangentic-secretstream-nonce-responder", XCHACHA_NONCE_LENGTH);
|
|
4151
|
+
const initiatorState = new SecretstreamState(initiatorKey, initiatorNonceHeader);
|
|
4152
|
+
const responderState = new SecretstreamState(responderKey, responderNonceHeader);
|
|
4153
|
+
return isInitiator ? { send: initiatorState, receive: responderState } : { send: responderState, receive: initiatorState };
|
|
4154
|
+
}
|
|
4155
|
+
|
|
4156
|
+
// src/crypto/sas.ts
|
|
4157
|
+
var SAS_LABEL = "kangentic-pairing-sas";
|
|
4158
|
+
var SAS_EMOJI_TABLE = [
|
|
4159
|
+
"\u{1F436}",
|
|
4160
|
+
"\u{1F431}",
|
|
4161
|
+
"\u{1F42D}",
|
|
4162
|
+
"\u{1F439}",
|
|
4163
|
+
"\u{1F430}",
|
|
4164
|
+
"\u{1F98A}",
|
|
4165
|
+
"\u{1F43B}",
|
|
4166
|
+
"\u{1F43C}",
|
|
4167
|
+
"\u{1F428}",
|
|
4168
|
+
"\u{1F42F}",
|
|
4169
|
+
"\u{1F981}",
|
|
4170
|
+
"\u{1F42E}",
|
|
4171
|
+
"\u{1F437}",
|
|
4172
|
+
"\u{1F438}",
|
|
4173
|
+
"\u{1F435}",
|
|
4174
|
+
"\u{1F414}",
|
|
4175
|
+
"\u{1F427}",
|
|
4176
|
+
"\u{1F426}",
|
|
4177
|
+
"\u{1F984}",
|
|
4178
|
+
"\u{1F434}",
|
|
4179
|
+
"\u{1F41D}",
|
|
4180
|
+
"\u{1F422}",
|
|
4181
|
+
"\u{1F40D}",
|
|
4182
|
+
"\u{1F419}",
|
|
4183
|
+
"\u{1F980}",
|
|
4184
|
+
"\u{1F433}",
|
|
4185
|
+
"\u{1F42C}",
|
|
4186
|
+
"\u{1F420}",
|
|
4187
|
+
"\u{1F98B}",
|
|
4188
|
+
"\u{1F40C}",
|
|
4189
|
+
"\u{1F41E}",
|
|
4190
|
+
"\u{1F982}",
|
|
4191
|
+
"\u{1F335}",
|
|
4192
|
+
"\u{1F332}",
|
|
4193
|
+
"\u{1F338}",
|
|
4194
|
+
"\u{1F340}",
|
|
4195
|
+
"\u{1F34E}",
|
|
4196
|
+
"\u{1F34C}",
|
|
4197
|
+
"\u{1F349}",
|
|
4198
|
+
"\u{1F347}",
|
|
4199
|
+
"\u{1F353}",
|
|
4200
|
+
"\u{1F352}",
|
|
4201
|
+
"\u{1F951}",
|
|
4202
|
+
"\u{1F33D}",
|
|
4203
|
+
"\u{1F355}",
|
|
4204
|
+
"\u{1F354}",
|
|
4205
|
+
"\u{1F369}",
|
|
4206
|
+
"\u{1F382}",
|
|
4207
|
+
"\u26BD",
|
|
4208
|
+
"\u{1F3C0}",
|
|
4209
|
+
"\u{1F3B8}",
|
|
4210
|
+
"\u{1F3B2}",
|
|
4211
|
+
"\u{1F3AF}",
|
|
4212
|
+
"\u{1F697}",
|
|
4213
|
+
"\u{1F680}",
|
|
4214
|
+
"\u26F5",
|
|
4215
|
+
"\u{1F6B2}",
|
|
4216
|
+
"\u231B",
|
|
4217
|
+
"\u{1F511}",
|
|
4218
|
+
"\u{1F48E}",
|
|
4219
|
+
"\u{1F388}",
|
|
4220
|
+
"\u{1F381}",
|
|
4221
|
+
"\u{1F514}",
|
|
4222
|
+
"\u2B50"
|
|
4223
|
+
];
|
|
4224
|
+
function deriveSasBytes(handshakeHash) {
|
|
4225
|
+
return deriveLabeledKey(handshakeHash, SAS_LABEL, 9);
|
|
4226
|
+
}
|
|
4227
|
+
function deriveShortAuthenticationString(handshakeHash) {
|
|
4228
|
+
const bytes = deriveSasBytes(handshakeHash);
|
|
4229
|
+
const digitsRaw = bytes[0] * 2 ** 24 + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3];
|
|
4230
|
+
const digitsValue = digitsRaw % 1e6;
|
|
4231
|
+
const digits = digitsValue.toString(10).padStart(6, "0");
|
|
4232
|
+
const emoji = [];
|
|
4233
|
+
for (let i = 0; i < 5; i++) {
|
|
4234
|
+
emoji.push(SAS_EMOJI_TABLE[bytes[4 + i] % SAS_EMOJI_TABLE.length]);
|
|
4235
|
+
}
|
|
4236
|
+
return { digits, emoji };
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
// src/capabilities/verbs.ts
|
|
4240
|
+
var CAPABILITY_VERBS = [
|
|
4241
|
+
"read-stream",
|
|
4242
|
+
"read-board",
|
|
4243
|
+
"read-diff",
|
|
4244
|
+
"send-user-message",
|
|
4245
|
+
"move-task",
|
|
4246
|
+
"answer-permission-prompt"
|
|
4247
|
+
];
|
|
4248
|
+
function isCapabilityVerb(value) {
|
|
4249
|
+
return CAPABILITY_VERBS.includes(value);
|
|
4250
|
+
}
|
|
4251
|
+
function capabilitySetFromArray(verbs) {
|
|
4252
|
+
const set = /* @__PURE__ */ new Set();
|
|
4253
|
+
for (const verb of verbs) {
|
|
4254
|
+
if (isCapabilityVerb(verb)) set.add(verb);
|
|
4255
|
+
}
|
|
4256
|
+
return set;
|
|
4257
|
+
}
|
|
4258
|
+
function capabilitySetToArray(capabilities) {
|
|
4259
|
+
return Array.from(capabilities);
|
|
4260
|
+
}
|
|
4261
|
+
|
|
4262
|
+
// src/wire/framing.ts
|
|
4263
|
+
var MAX_FRAME_LENGTH = 1024 * 1024;
|
|
4264
|
+
function encodeMessage(message) {
|
|
4265
|
+
const bytes = new TextEncoder().encode(JSON.stringify(message));
|
|
4266
|
+
if (bytes.length > MAX_FRAME_LENGTH) {
|
|
4267
|
+
throw new Error(`Encoded bridge message exceeds ${MAX_FRAME_LENGTH} bytes`);
|
|
4268
|
+
}
|
|
4269
|
+
return bytes;
|
|
4270
|
+
}
|
|
4271
|
+
function decodeMessage(bytes) {
|
|
4272
|
+
if (bytes.length > MAX_FRAME_LENGTH) {
|
|
4273
|
+
throw new Error(`Bridge message frame exceeds ${MAX_FRAME_LENGTH} bytes`);
|
|
4274
|
+
}
|
|
4275
|
+
const parsed = JSON.parse(new TextDecoder().decode(bytes));
|
|
4276
|
+
return validateBridgeMessage(parsed);
|
|
4277
|
+
}
|
|
4278
|
+
function isJsonValue(value) {
|
|
4279
|
+
if (value === null) return true;
|
|
4280
|
+
const t = typeof value;
|
|
4281
|
+
if (t === "boolean" || t === "number" || t === "string") return true;
|
|
4282
|
+
if (Array.isArray(value)) return value.every(isJsonValue);
|
|
4283
|
+
if (t === "object") return Object.values(value).every(isJsonValue);
|
|
4284
|
+
return false;
|
|
4285
|
+
}
|
|
4286
|
+
function isRecord(value) {
|
|
4287
|
+
return typeof value === "object" && value !== null;
|
|
4288
|
+
}
|
|
4289
|
+
function validateBridgeMessage(value) {
|
|
4290
|
+
if (!isRecord(value) || typeof value.type !== "string") {
|
|
4291
|
+
throw new Error('Invalid bridge message: missing "type"');
|
|
4292
|
+
}
|
|
4293
|
+
switch (value.type) {
|
|
4294
|
+
case "heartbeat":
|
|
4295
|
+
return { type: "heartbeat" };
|
|
4296
|
+
case "capability-request": {
|
|
4297
|
+
if (typeof value.requestId !== "string") throw new Error('capability-request missing "requestId"');
|
|
4298
|
+
if (typeof value.verb !== "string" || !isCapabilityVerb(value.verb)) throw new Error('capability-request has an invalid "verb"');
|
|
4299
|
+
if (!isJsonValue(value.payload)) throw new Error('capability-request has a non-JSON "payload"');
|
|
4300
|
+
return { type: "capability-request", requestId: value.requestId, verb: value.verb, payload: value.payload };
|
|
4301
|
+
}
|
|
4302
|
+
case "capability-response": {
|
|
4303
|
+
if (typeof value.requestId !== "string") throw new Error('capability-response missing "requestId"');
|
|
4304
|
+
if (typeof value.ok !== "boolean") throw new Error('capability-response missing "ok"');
|
|
4305
|
+
if (value.payload !== void 0 && !isJsonValue(value.payload)) throw new Error('capability-response has a non-JSON "payload"');
|
|
4306
|
+
if (value.error !== void 0 && typeof value.error !== "string") throw new Error('capability-response has a non-string "error"');
|
|
4307
|
+
return {
|
|
4308
|
+
type: "capability-response",
|
|
4309
|
+
requestId: value.requestId,
|
|
4310
|
+
ok: value.ok,
|
|
4311
|
+
payload: value.payload,
|
|
4312
|
+
error: value.error
|
|
4313
|
+
};
|
|
4314
|
+
}
|
|
4315
|
+
case "event": {
|
|
4316
|
+
const event = value.event;
|
|
4317
|
+
if (!isRecord(event) || typeof event.kind !== "string") {
|
|
4318
|
+
throw new Error('event message missing a valid "event"');
|
|
4319
|
+
}
|
|
4320
|
+
if (typeof event.taskId !== "string") throw new Error('event is missing "taskId"');
|
|
4321
|
+
if (!isJsonValue(event.payload)) throw new Error("event payload is not JSON-serializable");
|
|
4322
|
+
if (event.kind === "transcript" || event.kind === "activity") {
|
|
4323
|
+
if (typeof event.sessionId !== "string") throw new Error(`"${event.kind}" event is missing "sessionId"`);
|
|
4324
|
+
} else if (event.kind !== "board") {
|
|
4325
|
+
throw new Error(`event message has an unknown event kind: ${event.kind}`);
|
|
4326
|
+
}
|
|
4327
|
+
return { type: "event", event };
|
|
4328
|
+
}
|
|
4329
|
+
default:
|
|
4330
|
+
throw new Error(`Unknown bridge message type: ${value.type}`);
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
|
|
4334
|
+
// src/wire/session-frame.ts
|
|
4335
|
+
var SessionFrameKind = {
|
|
4336
|
+
Handshake: 0,
|
|
4337
|
+
Application: 1
|
|
4338
|
+
};
|
|
4339
|
+
function wrapSessionFrame(kind, payload) {
|
|
4340
|
+
const wrapped = new Uint8Array(payload.length + 1);
|
|
4341
|
+
wrapped[0] = kind;
|
|
4342
|
+
wrapped.set(payload, 1);
|
|
4343
|
+
return wrapped;
|
|
4344
|
+
}
|
|
4345
|
+
function unwrapSessionFrame(frame) {
|
|
4346
|
+
if (frame.length < 1) throw new Error("Session frame is too short to contain a kind byte");
|
|
4347
|
+
const kind = frame[0];
|
|
4348
|
+
if (kind !== SessionFrameKind.Handshake && kind !== SessionFrameKind.Application) {
|
|
4349
|
+
throw new Error(`Unknown session frame kind: ${kind}`);
|
|
4350
|
+
}
|
|
4351
|
+
return { kind, payload: frame.subarray(1) };
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
// src/wire/base64url.ts
|
|
4355
|
+
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
4356
|
+
var DECODE_MAP = {};
|
|
4357
|
+
for (let i = 0; i < ALPHABET.length; i++) DECODE_MAP[ALPHABET[i]] = i;
|
|
4358
|
+
function base64UrlEncode(bytes) {
|
|
4359
|
+
let result = "";
|
|
4360
|
+
let i = 0;
|
|
4361
|
+
for (; i + 2 < bytes.length; i += 3) {
|
|
4362
|
+
const chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
4363
|
+
result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63] + ALPHABET[chunk >> 6 & 63] + ALPHABET[chunk & 63];
|
|
4364
|
+
}
|
|
4365
|
+
const remaining = bytes.length - i;
|
|
4366
|
+
if (remaining === 1) {
|
|
4367
|
+
const chunk = bytes[i] << 16;
|
|
4368
|
+
result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63];
|
|
4369
|
+
} else if (remaining === 2) {
|
|
4370
|
+
const chunk = bytes[i] << 16 | bytes[i + 1] << 8;
|
|
4371
|
+
result += ALPHABET[chunk >> 18 & 63] + ALPHABET[chunk >> 12 & 63] + ALPHABET[chunk >> 6 & 63];
|
|
4372
|
+
}
|
|
4373
|
+
return result;
|
|
4374
|
+
}
|
|
4375
|
+
function base64UrlDecode(encoded) {
|
|
4376
|
+
const byteLength = Math.floor(encoded.length * 6 / 8);
|
|
4377
|
+
const bytes = new Uint8Array(byteLength);
|
|
4378
|
+
let bitBuffer = 0;
|
|
4379
|
+
let bitCount = 0;
|
|
4380
|
+
let outputIndex = 0;
|
|
4381
|
+
for (const char of encoded) {
|
|
4382
|
+
const value = DECODE_MAP[char];
|
|
4383
|
+
if (value === void 0) throw new Error(`Invalid base64url character: "${char}"`);
|
|
4384
|
+
bitBuffer = bitBuffer << 6 | value;
|
|
4385
|
+
bitCount += 6;
|
|
4386
|
+
if (bitCount >= 8) {
|
|
4387
|
+
bitCount -= 8;
|
|
4388
|
+
bytes[outputIndex] = bitBuffer >> bitCount & 255;
|
|
4389
|
+
outputIndex += 1;
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
return bytes;
|
|
4393
|
+
}
|
|
4394
|
+
|
|
4395
|
+
// src/pairing/qr.ts
|
|
4396
|
+
var PAIRING_URI_SCHEME = "kangentic-pair";
|
|
4397
|
+
var PAYLOAD_VERSION = 1;
|
|
4398
|
+
var PAIRING_TOKEN_LENGTH = 32;
|
|
4399
|
+
var MAX_RELAY_ADDRESS_LENGTH = 512;
|
|
4400
|
+
var MAX_PAYLOAD_LENGTH = 4096;
|
|
4401
|
+
function writeUint32(value) {
|
|
4402
|
+
const bytes = new Uint8Array(4);
|
|
4403
|
+
new DataView(bytes.buffer).setUint32(0, value, false);
|
|
4404
|
+
return bytes;
|
|
4405
|
+
}
|
|
4406
|
+
function readUint32(bytes, offset) {
|
|
4407
|
+
return new DataView(bytes.buffer, bytes.byteOffset + offset, 4).getUint32(0, false);
|
|
4408
|
+
}
|
|
4409
|
+
function encodePairingQrPayload(payload) {
|
|
4410
|
+
if (payload.desktopStaticPublicKey.length !== X25519_KEY_LENGTH) {
|
|
4411
|
+
throw new Error(`desktopStaticPublicKey must be ${X25519_KEY_LENGTH} bytes`);
|
|
4412
|
+
}
|
|
4413
|
+
if (payload.pairingToken.length !== PAIRING_TOKEN_LENGTH) {
|
|
4414
|
+
throw new Error(`pairingToken must be ${PAIRING_TOKEN_LENGTH} bytes`);
|
|
4415
|
+
}
|
|
4416
|
+
const relayAddressBytes = new TextEncoder().encode(payload.relayAddress);
|
|
4417
|
+
if (relayAddressBytes.length > MAX_RELAY_ADDRESS_LENGTH) {
|
|
4418
|
+
throw new Error(`relayAddress exceeds ${MAX_RELAY_ADDRESS_LENGTH} bytes`);
|
|
4419
|
+
}
|
|
4420
|
+
const expiresAtBytes = new TextEncoder().encode(payload.expiresAt);
|
|
4421
|
+
const protocolVersionBytes = new TextEncoder().encode(payload.protocolVersion);
|
|
4422
|
+
const body = concatBytes4(
|
|
4423
|
+
Uint8Array.of(PAYLOAD_VERSION),
|
|
4424
|
+
payload.desktopStaticPublicKey,
|
|
4425
|
+
payload.pairingToken,
|
|
4426
|
+
writeUint32(relayAddressBytes.length),
|
|
4427
|
+
relayAddressBytes,
|
|
4428
|
+
writeUint32(expiresAtBytes.length),
|
|
4429
|
+
expiresAtBytes,
|
|
4430
|
+
writeUint32(protocolVersionBytes.length),
|
|
4431
|
+
protocolVersionBytes
|
|
4432
|
+
);
|
|
4433
|
+
if (body.length > MAX_PAYLOAD_LENGTH) {
|
|
4434
|
+
throw new Error(`Pairing QR payload exceeds ${MAX_PAYLOAD_LENGTH} bytes`);
|
|
4435
|
+
}
|
|
4436
|
+
return `${PAIRING_URI_SCHEME}://${base64UrlEncode(body)}`;
|
|
4437
|
+
}
|
|
4438
|
+
function decodePairingQrPayload(uri) {
|
|
4439
|
+
const prefix = `${PAIRING_URI_SCHEME}://`;
|
|
4440
|
+
if (!uri.startsWith(prefix)) throw new Error("Not a kangentic pairing URI");
|
|
4441
|
+
const encoded = uri.slice(prefix.length);
|
|
4442
|
+
if (encoded.length > MAX_PAYLOAD_LENGTH * 2) {
|
|
4443
|
+
throw new Error("Pairing QR payload is too large");
|
|
4444
|
+
}
|
|
4445
|
+
const body = base64UrlDecode(encoded);
|
|
4446
|
+
if (body.length > MAX_PAYLOAD_LENGTH) throw new Error("Pairing QR payload is too large");
|
|
4447
|
+
if (body.length < 1 + X25519_KEY_LENGTH + PAIRING_TOKEN_LENGTH + 4) throw new Error("Pairing QR payload is too short");
|
|
4448
|
+
let offset = 0;
|
|
4449
|
+
const version = body[offset];
|
|
4450
|
+
offset += 1;
|
|
4451
|
+
if (version !== PAYLOAD_VERSION) throw new Error(`Unsupported pairing QR payload version: ${version}`);
|
|
4452
|
+
const desktopStaticPublicKey = body.subarray(offset, offset + X25519_KEY_LENGTH);
|
|
4453
|
+
offset += X25519_KEY_LENGTH;
|
|
4454
|
+
const pairingToken = body.subarray(offset, offset + PAIRING_TOKEN_LENGTH);
|
|
4455
|
+
offset += PAIRING_TOKEN_LENGTH;
|
|
4456
|
+
const relayAddressLength = readUint32(body, offset);
|
|
4457
|
+
offset += 4;
|
|
4458
|
+
if (relayAddressLength > MAX_RELAY_ADDRESS_LENGTH || offset + relayAddressLength > body.length) {
|
|
4459
|
+
throw new Error("Pairing QR payload has an invalid relay address length");
|
|
4460
|
+
}
|
|
4461
|
+
const relayAddress = new TextDecoder().decode(body.subarray(offset, offset + relayAddressLength));
|
|
4462
|
+
offset += relayAddressLength;
|
|
4463
|
+
if (offset + 4 > body.length) throw new Error("Pairing QR payload is missing an expiresAt length");
|
|
4464
|
+
const expiresAtLength = readUint32(body, offset);
|
|
4465
|
+
offset += 4;
|
|
4466
|
+
if (offset + expiresAtLength > body.length) throw new Error("Pairing QR payload has an invalid expiresAt length");
|
|
4467
|
+
const expiresAt = new TextDecoder().decode(body.subarray(offset, offset + expiresAtLength));
|
|
4468
|
+
offset += expiresAtLength;
|
|
4469
|
+
if (offset + 4 > body.length) throw new Error("Pairing QR payload is missing a protocol version");
|
|
4470
|
+
const protocolVersionLength = readUint32(body, offset);
|
|
4471
|
+
offset += 4;
|
|
4472
|
+
if (offset + protocolVersionLength > body.length) throw new Error("Pairing QR payload has an invalid protocolVersion length");
|
|
4473
|
+
const protocolVersion = new TextDecoder().decode(body.subarray(offset, offset + protocolVersionLength));
|
|
4474
|
+
return { desktopStaticPublicKey, pairingToken, relayAddress, expiresAt, protocolVersion };
|
|
4475
|
+
}
|
|
4476
|
+
|
|
4477
|
+
// src/roster/roster.ts
|
|
4478
|
+
function uint32LengthPrefixed(bytes) {
|
|
4479
|
+
const prefix = new Uint8Array(4);
|
|
4480
|
+
new DataView(prefix.buffer).setUint32(0, bytes.length, false);
|
|
4481
|
+
return concatBytes4(prefix, bytes);
|
|
4482
|
+
}
|
|
4483
|
+
function encodeRosterEntryForSigning(entry) {
|
|
4484
|
+
const encoder = new TextEncoder();
|
|
4485
|
+
const sortedCapabilities = entry.capabilities.slice().sort().join(",");
|
|
4486
|
+
return concatBytes4(
|
|
4487
|
+
uint32LengthPrefixed(encoder.encode(entry.deviceId)),
|
|
4488
|
+
uint32LengthPrefixed(entry.staticPublicKey),
|
|
4489
|
+
uint32LengthPrefixed(encoder.encode(entry.displayName)),
|
|
4490
|
+
uint32LengthPrefixed(encoder.encode(sortedCapabilities)),
|
|
4491
|
+
uint32LengthPrefixed(encoder.encode(entry.pairedAt)),
|
|
4492
|
+
uint32LengthPrefixed(encoder.encode(entry.expiresAt ?? ""))
|
|
4493
|
+
);
|
|
4494
|
+
}
|
|
4495
|
+
function signRosterEntry(masterSigningSecretKey, entry) {
|
|
4496
|
+
const signature = ed25519Sign(encodeRosterEntryForSigning(entry), masterSigningSecretKey);
|
|
4497
|
+
return { ...entry, signature };
|
|
4498
|
+
}
|
|
4499
|
+
function verifyRosterEntry(masterSigningPublicKey, entry) {
|
|
4500
|
+
return ed25519Verify(entry.signature, encodeRosterEntryForSigning(entry), masterSigningPublicKey);
|
|
4501
|
+
}
|
|
4502
|
+
function isRosterEntryExpired(entry, now) {
|
|
4503
|
+
if (entry.expiresAt === null) return false;
|
|
4504
|
+
return new Date(entry.expiresAt).getTime() <= now.getTime();
|
|
4505
|
+
}
|
|
4506
|
+
function findRosterDevice(roster, deviceId) {
|
|
4507
|
+
return roster.devices.find((device) => device.deviceId === deviceId);
|
|
4508
|
+
}
|
|
4509
|
+
function rosterDeviceCapabilitySet(entry) {
|
|
4510
|
+
return capabilitySetFromArray(entry.capabilities);
|
|
4511
|
+
}
|
|
4512
|
+
function capabilitySetToRosterCapabilities(capabilities) {
|
|
4513
|
+
return capabilitySetToArray(capabilities);
|
|
4514
|
+
}
|
|
4515
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
4516
|
+
0 && (module.exports = {
|
|
4517
|
+
CAPABILITY_VERBS,
|
|
4518
|
+
CipherState,
|
|
4519
|
+
ED25519_KEY_LENGTH,
|
|
4520
|
+
FrameTag,
|
|
4521
|
+
HandshakeState,
|
|
4522
|
+
IKPSK0_PATTERN,
|
|
4523
|
+
KK_PATTERN,
|
|
4524
|
+
MAX_FRAME_LENGTH,
|
|
4525
|
+
PAIRING_URI_SCHEME,
|
|
4526
|
+
PROTOCOL_VERSION,
|
|
4527
|
+
SecretstreamState,
|
|
4528
|
+
SessionFrameKind,
|
|
4529
|
+
X25519_KEY_LENGTH,
|
|
4530
|
+
bytesToHex,
|
|
4531
|
+
capabilitySetFromArray,
|
|
4532
|
+
capabilitySetToArray,
|
|
4533
|
+
capabilitySetToRosterCapabilities,
|
|
4534
|
+
createKKHandshake,
|
|
4535
|
+
createPairingInitiatorHandshake,
|
|
4536
|
+
createPairingResponderHandshake,
|
|
4537
|
+
decodeMessage,
|
|
4538
|
+
decodePairingQrPayload,
|
|
4539
|
+
deriveSecretstreamPair,
|
|
4540
|
+
deriveShortAuthenticationString,
|
|
4541
|
+
encodeMessage,
|
|
4542
|
+
encodePairingQrPayload,
|
|
4543
|
+
encodeProtocolVersion,
|
|
4544
|
+
encodeRosterEntryForSigning,
|
|
4545
|
+
findRosterDevice,
|
|
4546
|
+
generateEd25519KeyPair,
|
|
4547
|
+
generateX25519KeyPair,
|
|
4548
|
+
hexToBytes,
|
|
4549
|
+
isCapabilityVerb,
|
|
4550
|
+
isRosterEntryExpired,
|
|
4551
|
+
randomBytes,
|
|
4552
|
+
rosterDeviceCapabilitySet,
|
|
4553
|
+
signRosterEntry,
|
|
4554
|
+
unwrapSessionFrame,
|
|
4555
|
+
verifyRosterEntry,
|
|
4556
|
+
wrapSessionFrame,
|
|
4557
|
+
x25519PublicKeyFrom
|
|
4558
|
+
});
|
|
4559
|
+
/*! Bundled license information:
|
|
4560
|
+
|
|
4561
|
+
@noble/curves/utils.js:
|
|
4562
|
+
@noble/curves/abstract/modular.js:
|
|
4563
|
+
@noble/curves/abstract/curve.js:
|
|
4564
|
+
@noble/curves/abstract/edwards.js:
|
|
4565
|
+
@noble/curves/abstract/montgomery.js:
|
|
4566
|
+
@noble/curves/ed25519.js:
|
|
4567
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
4568
|
+
|
|
4569
|
+
@noble/ciphers/utils.js:
|
|
4570
|
+
(*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) *)
|
|
4571
|
+
*/
|