@blockcast/mmt-container 0.4.1 → 0.5.0-main.34c7b9c2cfa0
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/README.md +2 -2
- package/dist/browser-runtime.js +3769 -364
- package/dist/browser-runtime.js.map +4 -4
- package/dist/cmcd-producer.d.ts +5 -1
- package/dist/cmcd-producer.d.ts.map +1 -1
- package/dist/cmcd-producer.js.map +2 -2
- package/dist/delivery-catalog.js +18 -2
- package/dist/delivery-catalog.js.map +2 -2
- package/dist/fec-manager.d.ts +21 -16
- package/dist/fec-manager.d.ts.map +1 -1
- package/dist/fec-manager.js +197 -80
- package/dist/fec-manager.js.map +3 -3
- package/dist/held-layer-admission.d.ts +58 -0
- package/dist/held-layer-admission.d.ts.map +1 -0
- package/dist/held-layer-admission.js +105 -0
- package/dist/held-layer-admission.js.map +7 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +2 -2
- package/dist/mmtp-container-parser.d.ts +10 -0
- package/dist/mmtp-container-parser.d.ts.map +1 -1
- package/dist/mmtp-container-parser.js +31 -1
- package/dist/mmtp-container-parser.js.map +2 -2
- package/dist/mmtp-container-parser.no-modules.js +2713 -1024
- package/dist/mmtp-container-parser.no-modules.js.map +4 -4
- package/dist/mmtp-decode-pipeline.js +31 -1
- package/dist/mmtp-decode-pipeline.js.map +2 -2
- package/dist/mmtp-fec-session.d.ts +36 -3
- package/dist/mmtp-fec-session.d.ts.map +1 -1
- package/dist/mmtp-fec-session.js +114 -5
- package/dist/mmtp-fec-session.js.map +3 -3
- package/dist/mmtp-router.d.ts +96 -29
- package/dist/mmtp-router.d.ts.map +1 -1
- package/dist/mmtp-router.js +522 -205
- package/dist/mmtp-router.js.map +2 -2
- package/dist/multicast-auth-catalog.d.ts +10 -2
- package/dist/multicast-auth-catalog.d.ts.map +1 -1
- package/dist/multicast-auth-catalog.js +422 -22
- package/dist/multicast-auth-catalog.js.map +4 -4
- package/dist/multicast-manager.d.ts +78 -11
- package/dist/multicast-manager.d.ts.map +1 -1
- package/dist/multicast-manager.js +3663 -333
- package/dist/multicast-manager.js.map +4 -4
- package/dist/multicast-transport.d.ts +4 -1
- package/dist/multicast-transport.d.ts.map +1 -1
- package/dist/multicast-transport.js +20 -3
- package/dist/multicast-transport.js.map +2 -2
- package/dist/no-modules.d.ts +1 -2
- package/dist/no-modules.d.ts.map +1 -1
- package/dist/no-modules.js +2699 -1008
- package/dist/no-modules.js.map +4 -4
- package/dist/repair-fetch.d.ts +50 -10
- package/dist/repair-fetch.d.ts.map +1 -1
- package/dist/repair-fetch.js +62 -20
- package/dist/repair-fetch.js.map +2 -2
- package/dist/wasm-mmtp-container-parser.js +31 -1
- package/dist/wasm-mmtp-container-parser.js.map +2 -2
- package/package.json +7 -15
- package/src/cmcd-producer.ts +6 -1
- package/src/fec-manager.ts +147 -131
- package/src/held-layer-admission.ts +161 -0
- package/src/index.ts +6 -9
- package/src/mmtp-container-parser.ts +48 -0
- package/src/mmtp-fec-session.ts +76 -3
- package/src/mmtp-router.ts +637 -274
- package/src/multicast-auth-catalog.ts +81 -8
- package/src/multicast-manager.ts +274 -49
- package/src/multicast-transport.ts +6 -2
- package/src/no-modules.ts +1 -6
- package/src/repair-fetch.ts +154 -34
- package/test-vectors/catalog/negative/multicast-auth-padded-key.json +0 -1
- package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +0 -1
- package/test-vectors/catalog/negative/multicast-auth-root-dotted-key.json +0 -1
- package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +0 -1
- package/test-vectors/repair-policy-v1.json +113 -0
- package/dist/manifest-auth-plan.d.ts +0 -31
- package/dist/manifest-auth-plan.d.ts.map +0 -1
- package/dist/manifest-auth-plan.js +0 -426
- package/dist/manifest-auth-plan.js.map +0 -7
- package/dist/source-auth.d.ts +0 -2
- package/dist/source-auth.d.ts.map +0 -1
- package/dist/source-auth.js +0 -3912
- package/dist/source-auth.js.map +0 -7
- package/src/manifest-auth-plan.ts +0 -55
- package/src/source-auth.ts +0 -1
- package/test-vectors/generate-source-auth-fixture.mjs +0 -114
- package/test-vectors/source-auth-v1.json +0 -61
package/dist/no-modules.js
CHANGED
|
@@ -5568,6 +5568,9 @@ function authoredGap(before, after) {
|
|
|
5568
5568
|
if (!a || !b || a.mediaTimescale !== b.mediaTimescale) return false;
|
|
5569
5569
|
return b.decodeTime > a.decodeTime + BigInt(a.durationTicks);
|
|
5570
5570
|
}
|
|
5571
|
+
function ssIdAfter(a, b) {
|
|
5572
|
+
return (a - b | 0) > 0;
|
|
5573
|
+
}
|
|
5571
5574
|
var FecReleaseSequencer = class {
|
|
5572
5575
|
#streams = /* @__PURE__ */ new Map();
|
|
5573
5576
|
#gate;
|
|
@@ -5629,11 +5632,17 @@ var FecReleaseSequencer = class {
|
|
|
5629
5632
|
stream.last = null;
|
|
5630
5633
|
stream.lastSbn = void 0;
|
|
5631
5634
|
stream.discontinuity = false;
|
|
5635
|
+
stream.rapSsId = void 0;
|
|
5632
5636
|
}
|
|
5633
5637
|
if (stream.last !== null && compareFrameOrder(frame, stream.last) <= 0) {
|
|
5634
5638
|
this.#recordStat("droppedStale");
|
|
5635
5639
|
return;
|
|
5636
5640
|
}
|
|
5641
|
+
const ssId = meta.fecSbn;
|
|
5642
|
+
if (meta.trackType === "video" && ssId !== void 0 && this.#gate.isRap?.(data, meta) === true) {
|
|
5643
|
+
if (stream.rapSsId === void 0 || ssIdAfter(ssId, stream.rapSsId)) stream.rapSsId = ssId;
|
|
5644
|
+
this.#gate.onRap?.(stream.packetId, stream.catalogTrackName, ssId);
|
|
5645
|
+
}
|
|
5637
5646
|
if (stream.last === null) {
|
|
5638
5647
|
if (meta.trackType === "video" && !meta.keyframe) {
|
|
5639
5648
|
this.#recordStat("droppedBeforeStartupKeyframe");
|
|
@@ -5669,6 +5678,22 @@ var FecReleaseSequencer = class {
|
|
|
5669
5678
|
}
|
|
5670
5679
|
return earliest;
|
|
5671
5680
|
}
|
|
5681
|
+
/**
|
|
5682
|
+
* Whether a complete RAP above SS_ID `ssId` entered the gate of a stream of
|
|
5683
|
+
* `packetId` (draft-ramadan-moq-fec 11.4.2: repair of a block below it is
|
|
5684
|
+
* moot). Its SS_ID is the one its frame completed in; a frame's packets
|
|
5685
|
+
* hold consecutive SS_IDs in authored order, so a complete RAP with a
|
|
5686
|
+
* packet above `ssId` has every packet of it at or above the first SS_ID
|
|
5687
|
+
* any loss at or below `ssId` could have taken.
|
|
5688
|
+
*/
|
|
5689
|
+
rapAbove(packetId, catalogTrackName, ssId) {
|
|
5690
|
+
for (const stream of this.#streams.values()) {
|
|
5691
|
+
if (stream.packetId !== packetId) continue;
|
|
5692
|
+
if (catalogTrackName !== void 0 && stream.catalogTrackName !== catalogTrackName) continue;
|
|
5693
|
+
if (stream.rapSsId !== void 0 && ssIdAfter(stream.rapSsId, ssId)) return true;
|
|
5694
|
+
}
|
|
5695
|
+
return false;
|
|
5696
|
+
}
|
|
5672
5697
|
/** Re-evaluate held gaps after FEC state changed. */
|
|
5673
5698
|
poke(streamKey) {
|
|
5674
5699
|
if (streamKey !== void 0) {
|
|
@@ -5759,7 +5784,8 @@ var FecReleaseSequencer = class {
|
|
|
5759
5784
|
buf: [],
|
|
5760
5785
|
last: null,
|
|
5761
5786
|
lastSbn: void 0,
|
|
5762
|
-
discontinuity: false
|
|
5787
|
+
discontinuity: false,
|
|
5788
|
+
rapSsId: void 0
|
|
5763
5789
|
};
|
|
5764
5790
|
this.#streams.set(streamKey, stream);
|
|
5765
5791
|
}
|
|
@@ -6122,6 +6148,10 @@ var MmtpContainerParser = class _MmtpContainerParser {
|
|
|
6122
6148
|
fecReleaseEarliestHeldAtMs(packetId, catalogTrackName) {
|
|
6123
6149
|
return this.#fecSequencer?.earliestHeldArrivalMs(packetId, catalogTrackName);
|
|
6124
6150
|
}
|
|
6151
|
+
/** See FecReleaseSequencer.rapAbove; false when no stream is FEC-gated. */
|
|
6152
|
+
fecReleaseRapAbove(packetId, catalogTrackName, ssId) {
|
|
6153
|
+
return this.#fecSequencer?.rapAbove(packetId, catalogTrackName, ssId) ?? false;
|
|
6154
|
+
}
|
|
6125
6155
|
/** Re-evaluate held gaps after FEC block state changed. */
|
|
6126
6156
|
pokeFecRelease(packetId, catalogTrackName) {
|
|
6127
6157
|
if (!this.#fecSequencer) return;
|
|
@@ -8079,6 +8109,81 @@ function resolveFecState(evidence) {
|
|
|
8079
8109
|
|
|
8080
8110
|
// src/mmtp-fec-session.ts
|
|
8081
8111
|
import { deriveFecRetentionBlocks, fecBlockBudgetMs } from "@blockcast/mmt-fec";
|
|
8112
|
+
|
|
8113
|
+
// src/held-layer-admission.ts
|
|
8114
|
+
var HORIZON_CAP = 1073741824;
|
|
8115
|
+
function heldLayerAnchorHorizon(retentionBlocks, k) {
|
|
8116
|
+
return retentionBlocks === void 0 || k <= 0 ? HORIZON_CAP : Math.min(HORIZON_CAP, retentionBlocks * k);
|
|
8117
|
+
}
|
|
8118
|
+
var HeldLayerAdmission = class {
|
|
8119
|
+
#layerNames;
|
|
8120
|
+
#states;
|
|
8121
|
+
constructor(layers, heldLayers = [0]) {
|
|
8122
|
+
const held = new Set(heldLayers);
|
|
8123
|
+
this.#layerNames = new Set(layers.map((l) => l.repairTrackName));
|
|
8124
|
+
this.#states = layers.filter((l) => held.has(l.layer)).map((l) => ({ layer: l.layer, repairTrackName: l.repairTrackName, total: l.rsIdOffset + l.repairSymbols }));
|
|
8125
|
+
}
|
|
8126
|
+
/**
|
|
8127
|
+
* Judges one repair packet, after the 4.5 discards and the size check and
|
|
8128
|
+
* before it places a block. `repairTrackName` is the subscribed repair
|
|
8129
|
+
* track, never inferred from RS_ID; without it only (b) runs. A packet on a
|
|
8130
|
+
* repair track the catalog does not list is `'discard'` and anchors nothing.
|
|
8131
|
+
* `sourceFrontier` is the newest source SS_ID, if any: a repair more than
|
|
8132
|
+
* `horizon` past it is judged without moving the anchored state.
|
|
8133
|
+
*
|
|
8134
|
+
* @returns undefined to admit, `'discard'`, or the fail-closed reason.
|
|
8135
|
+
*/
|
|
8136
|
+
admit(repairTrackName, ssStart, rsbLength, horizon, sourceFrontier) {
|
|
8137
|
+
if (repairTrackName !== void 0 && !this.#layerNames.has(repairTrackName)) return "discard";
|
|
8138
|
+
const farAhead = sourceFrontier !== void 0 && serial32Precedes(sourceFrontier, ssStart) && serial32Distance(sourceFrontier, ssStart) > horizon;
|
|
8139
|
+
for (const state of this.#states) {
|
|
8140
|
+
let code;
|
|
8141
|
+
if (farAhead) {
|
|
8142
|
+
if (rsbLength < state.total) {
|
|
8143
|
+
if (state.layer > 0 && repairTrackName === state.repairTrackName) code = "below_own_track_total";
|
|
8144
|
+
else if (state.anchor !== void 0 || state.settled) code = "below_anchored_total";
|
|
8145
|
+
}
|
|
8146
|
+
} else {
|
|
8147
|
+
if (state.newest === void 0 || serial32Precedes(state.newest, ssStart)) state.newest = ssStart;
|
|
8148
|
+
const stale = (s) => serial32Distance(s, state.newest) > horizon;
|
|
8149
|
+
if (state.latestBelow !== void 0 && stale(state.latestBelow)) {
|
|
8150
|
+
delete state.latestBelow;
|
|
8151
|
+
delete state.latestBelowRsb;
|
|
8152
|
+
}
|
|
8153
|
+
if (state.anchor !== void 0 && stale(state.anchor)) state.settled = true;
|
|
8154
|
+
if (rsbLength < state.total) {
|
|
8155
|
+
if (state.layer > 0 && repairTrackName === state.repairTrackName) code = "below_own_track_total";
|
|
8156
|
+
else if (stale(ssStart)) continue;
|
|
8157
|
+
else if (state.settled || state.anchor !== void 0 && !serial32Precedes(ssStart, state.anchor)) code = "below_anchored_total";
|
|
8158
|
+
else if (state.latestBelow === void 0 || serial32Precedes(state.latestBelow, ssStart)) {
|
|
8159
|
+
state.latestBelow = ssStart;
|
|
8160
|
+
state.latestBelowRsb = rsbLength;
|
|
8161
|
+
}
|
|
8162
|
+
} else if (!state.settled && !stale(ssStart)) {
|
|
8163
|
+
if (state.anchor === void 0 || serial32Precedes(ssStart, state.anchor)) state.anchor = ssStart;
|
|
8164
|
+
if (state.latestBelow !== void 0 && !serial32Precedes(state.latestBelow, state.anchor)) {
|
|
8165
|
+
code = "below_anchored_total";
|
|
8166
|
+
ssStart = state.latestBelow;
|
|
8167
|
+
rsbLength = state.latestBelowRsb;
|
|
8168
|
+
}
|
|
8169
|
+
}
|
|
8170
|
+
}
|
|
8171
|
+
if (code !== void 0) {
|
|
8172
|
+
return {
|
|
8173
|
+
code,
|
|
8174
|
+
layer: state.layer,
|
|
8175
|
+
total: state.total,
|
|
8176
|
+
rsbLength,
|
|
8177
|
+
ssStart,
|
|
8178
|
+
...state.anchor === void 0 ? {} : { anchor: state.anchor }
|
|
8179
|
+
};
|
|
8180
|
+
}
|
|
8181
|
+
}
|
|
8182
|
+
return void 0;
|
|
8183
|
+
}
|
|
8184
|
+
};
|
|
8185
|
+
|
|
8186
|
+
// src/mmtp-fec-session.ts
|
|
8082
8187
|
var PATH_BITS = { moq: 1, multicast: 2 };
|
|
8083
8188
|
var MIXED_PATHS = PATH_BITS.moq | PATH_BITS.multicast;
|
|
8084
8189
|
var MmtpFecSession = class {
|
|
@@ -8096,6 +8201,9 @@ var MmtpFecSession = class {
|
|
|
8096
8201
|
/** The newest SS_ID when the remembered SS_IDs were last pruned. */
|
|
8097
8202
|
#prunedAt;
|
|
8098
8203
|
#repairPacketId;
|
|
8204
|
+
#newestSource;
|
|
8205
|
+
#heldLayers;
|
|
8206
|
+
#anchorHorizon;
|
|
8099
8207
|
#stats = {
|
|
8100
8208
|
sourceSymbols: 0,
|
|
8101
8209
|
repairSymbols: 0,
|
|
@@ -8108,11 +8216,12 @@ var MmtpFecSession = class {
|
|
|
8108
8216
|
dropped: {},
|
|
8109
8217
|
sourceSymbolsByPath: { moq: 0, multicast: 0 },
|
|
8110
8218
|
repairSymbolsByPath: { moq: 0, multicast: 0 },
|
|
8111
|
-
mixedPath: { clean: 0, recovered: 0, failed: 0, released: 0 }
|
|
8219
|
+
mixedPath: { clean: 0, recovered: 0, failed: 0, released: 0 },
|
|
8220
|
+
failClosed: null
|
|
8112
8221
|
};
|
|
8113
8222
|
/**
|
|
8114
8223
|
* @throws when the catalog block lacks or misstates a field the session
|
|
8115
|
-
* needs: the block profile, K, T, `interleaveDepthMs` or
|
|
8224
|
+
* needs: the block profile, K, P_0 (`repairSymbols`), T, `interleaveDepthMs` or
|
|
8116
8225
|
* `reorderToleranceMs`. None is defaulted.
|
|
8117
8226
|
*/
|
|
8118
8227
|
constructor(config) {
|
|
@@ -8126,6 +8235,7 @@ var MmtpFecSession = class {
|
|
|
8126
8235
|
}
|
|
8127
8236
|
this.algorithm = fec.algorithm === "reed-solomon" ? "reed-solomon" : "raptorq";
|
|
8128
8237
|
this.sourceSymbols = requirePositiveInteger(fec.sourceSymbols, "fec.sourceSymbols");
|
|
8238
|
+
this.repairSymbols = requirePositiveInteger(fec.repairSymbols, "fec.repairSymbols");
|
|
8129
8239
|
this.symbolSize = requirePositiveInteger(fec.symbolSize, "fec.symbolSize");
|
|
8130
8240
|
const interleaveDepthMs = requireNumber(fec.interleaveDepthMs, "fec.interleaveDepthMs");
|
|
8131
8241
|
const reorderToleranceMs = requireNumber(fec.reorderToleranceMs, "fec.reorderToleranceMs");
|
|
@@ -8133,6 +8243,18 @@ var MmtpFecSession = class {
|
|
|
8133
8243
|
fecBlockBudgetMs(interleaveDepthMs, reorderToleranceMs),
|
|
8134
8244
|
interleaveDepthMs
|
|
8135
8245
|
);
|
|
8246
|
+
this.#heldLayers = new HeldLayerAdmission(
|
|
8247
|
+
config.repairLayers ?? [
|
|
8248
|
+
{
|
|
8249
|
+
layer: 0,
|
|
8250
|
+
repairTrackName: typeof fec.repairTrack === "string" ? fec.repairTrack : "",
|
|
8251
|
+
rsIdOffset: 0,
|
|
8252
|
+
repairSymbols: this.repairSymbols
|
|
8253
|
+
}
|
|
8254
|
+
],
|
|
8255
|
+
config.heldLayers
|
|
8256
|
+
);
|
|
8257
|
+
this.#anchorHorizon = heldLayerAnchorHorizon(this.retentionBlocks, this.sourceSymbols);
|
|
8136
8258
|
if (typeof config.Decoder !== "function") {
|
|
8137
8259
|
throw new Error("MmtpFecSession: a decoder constructor (wasm_bindgen.MmtFecDecoder) is required");
|
|
8138
8260
|
}
|
|
@@ -8155,7 +8277,8 @@ var MmtpFecSession = class {
|
|
|
8155
8277
|
dropped: { ...this.#stats.dropped },
|
|
8156
8278
|
sourceSymbolsByPath: { ...this.#stats.sourceSymbolsByPath },
|
|
8157
8279
|
repairSymbolsByPath: { ...this.#stats.repairSymbolsByPath },
|
|
8158
|
-
mixedPath: { ...this.#stats.mixedPath }
|
|
8280
|
+
mixedPath: { ...this.#stats.mixedPath },
|
|
8281
|
+
failClosed: this.#stats.failClosed && { ...this.#stats.failClosed }
|
|
8159
8282
|
};
|
|
8160
8283
|
}
|
|
8161
8284
|
/**
|
|
@@ -8180,6 +8303,7 @@ var MmtpFecSession = class {
|
|
|
8180
8303
|
this.#stats.sourceSymbols++;
|
|
8181
8304
|
this.#stats.sourceSymbolsByPath[path]++;
|
|
8182
8305
|
this.#noteNewest(ssId);
|
|
8306
|
+
if (this.#newestSource === void 0 || serial32Precedes(this.#newestSource, ssId)) this.#newestSource = ssId;
|
|
8183
8307
|
const start = this.#blockStartOf(ssId);
|
|
8184
8308
|
const block = start === void 0 ? void 0 : this.#blocks.get(start);
|
|
8185
8309
|
if (block) {
|
|
@@ -8208,14 +8332,17 @@ var MmtpFecSession = class {
|
|
|
8208
8332
|
* Feeds one object of the repair track: a whole MMTP repair packet (ISO/IEC
|
|
8209
8333
|
* 23008-1 C.5.3). A repair track carries one repair flow, so the first
|
|
8210
8334
|
* repair packet fixes its packet ID and a packet of any other is refused.
|
|
8211
|
-
* `path` is where it was received, as for addSource().
|
|
8335
|
+
* `path` is where it was received, as for addSource(). `repairTrackName`
|
|
8336
|
+
* is the repair track it was received on, for the 6.3.9 own-track rule; a
|
|
8337
|
+
* track the layers do not list is refused as `repair:unlisted-track`.
|
|
8212
8338
|
*
|
|
8213
8339
|
* @returns the protected packets this repair symbol recovered, as for
|
|
8214
8340
|
* addSource().
|
|
8215
8341
|
*/
|
|
8216
|
-
addRepair(packet, path = "moq") {
|
|
8342
|
+
addRepair(packet, path = "moq", repairTrackName) {
|
|
8217
8343
|
const decoder = this.#decoder;
|
|
8218
8344
|
if (!decoder) return this.#drop("repair:released");
|
|
8345
|
+
if (this.#stats.failClosed) return this.#drop("repair:fail-closed");
|
|
8219
8346
|
const pathBit = PATH_BITS[path];
|
|
8220
8347
|
if (!pathBit) return this.#drop("repair:unknown-path");
|
|
8221
8348
|
let header;
|
|
@@ -8236,6 +8363,18 @@ var MmtpFecSession = class {
|
|
|
8236
8363
|
if (this.algorithm === "reed-solomon" && frame.ssbLength + frame.rsbLength > 255) {
|
|
8237
8364
|
return this.#drop("repair:rs-block-length");
|
|
8238
8365
|
}
|
|
8366
|
+
const verdict = this.#heldLayers.admit(
|
|
8367
|
+
repairTrackName,
|
|
8368
|
+
frame.ssStart,
|
|
8369
|
+
frame.rsbLength,
|
|
8370
|
+
this.#anchorHorizon,
|
|
8371
|
+
this.#newestSource
|
|
8372
|
+
);
|
|
8373
|
+
if (verdict === "discard") return this.#drop("repair:unlisted-track");
|
|
8374
|
+
if (verdict !== void 0) {
|
|
8375
|
+
this.#stats.failClosed = verdict;
|
|
8376
|
+
return this.#drop("repair:fail-closed");
|
|
8377
|
+
}
|
|
8239
8378
|
const start = frame.ssStart;
|
|
8240
8379
|
let block = this.#blocks.get(start);
|
|
8241
8380
|
if (block && block.ssbLength !== frame.ssbLength) return this.#drop("repair:conflicting-ssb-length");
|
|
@@ -9123,6 +9262,9 @@ var MmtpToCmaf = class {
|
|
|
9123
9262
|
}
|
|
9124
9263
|
};
|
|
9125
9264
|
|
|
9265
|
+
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/crypto.js
|
|
9266
|
+
var crypto = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : void 0;
|
|
9267
|
+
|
|
9126
9268
|
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/utils.js
|
|
9127
9269
|
function isBytes(a) {
|
|
9128
9270
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
@@ -9150,32 +9292,63 @@ function aoutput(out, instance) {
|
|
|
9150
9292
|
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
9151
9293
|
}
|
|
9152
9294
|
}
|
|
9153
|
-
function u8(arr) {
|
|
9154
|
-
return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
9155
|
-
}
|
|
9156
|
-
function u322(arr) {
|
|
9157
|
-
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
9158
|
-
}
|
|
9159
9295
|
function clean(...arrays) {
|
|
9160
9296
|
for (let i = 0; i < arrays.length; i++) {
|
|
9161
9297
|
arrays[i].fill(0);
|
|
9162
9298
|
}
|
|
9163
9299
|
}
|
|
9300
|
+
function createView(arr) {
|
|
9301
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
9302
|
+
}
|
|
9164
9303
|
function rotr(word, shift) {
|
|
9165
9304
|
return word << 32 - shift | word >>> shift;
|
|
9166
9305
|
}
|
|
9167
|
-
var
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
var
|
|
9172
|
-
function
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9306
|
+
var hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
9307
|
+
// @ts-ignore
|
|
9308
|
+
typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
|
|
9309
|
+
))();
|
|
9310
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
9311
|
+
function bytesToHex(bytes) {
|
|
9312
|
+
abytes(bytes);
|
|
9313
|
+
if (hasHexBuiltin)
|
|
9314
|
+
return bytes.toHex();
|
|
9315
|
+
let hex2 = "";
|
|
9316
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
9317
|
+
hex2 += hexes[bytes[i]];
|
|
9318
|
+
}
|
|
9319
|
+
return hex2;
|
|
9320
|
+
}
|
|
9321
|
+
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
9322
|
+
function asciiToBase16(ch) {
|
|
9323
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
9324
|
+
return ch - asciis._0;
|
|
9325
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
9326
|
+
return ch - (asciis.A - 10);
|
|
9327
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
9328
|
+
return ch - (asciis.a - 10);
|
|
9329
|
+
return;
|
|
9330
|
+
}
|
|
9331
|
+
function hexToBytes(hex2) {
|
|
9332
|
+
if (typeof hex2 !== "string")
|
|
9333
|
+
throw new Error("hex string expected, got " + typeof hex2);
|
|
9334
|
+
if (hasHexBuiltin)
|
|
9335
|
+
return Uint8Array.fromHex(hex2);
|
|
9336
|
+
const hl = hex2.length;
|
|
9337
|
+
const al = hl / 2;
|
|
9338
|
+
if (hl % 2)
|
|
9339
|
+
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
9340
|
+
const array = new Uint8Array(al);
|
|
9341
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
9342
|
+
const n1 = asciiToBase16(hex2.charCodeAt(hi));
|
|
9343
|
+
const n2 = asciiToBase16(hex2.charCodeAt(hi + 1));
|
|
9344
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
9345
|
+
const char = hex2[hi] + hex2[hi + 1];
|
|
9346
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
9347
|
+
}
|
|
9348
|
+
array[ai] = n1 * 16 + n2;
|
|
9349
|
+
}
|
|
9350
|
+
return array;
|
|
9177
9351
|
}
|
|
9178
|
-
var swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
9179
9352
|
function utf8ToBytes(str) {
|
|
9180
9353
|
if (typeof str !== "string")
|
|
9181
9354
|
throw new Error("string expected");
|
|
@@ -9187,114 +9360,126 @@ function toBytes(data) {
|
|
|
9187
9360
|
abytes(data);
|
|
9188
9361
|
return data;
|
|
9189
9362
|
}
|
|
9363
|
+
function concatBytes(...arrays) {
|
|
9364
|
+
let sum = 0;
|
|
9365
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
9366
|
+
const a = arrays[i];
|
|
9367
|
+
abytes(a);
|
|
9368
|
+
sum += a.length;
|
|
9369
|
+
}
|
|
9370
|
+
const res = new Uint8Array(sum);
|
|
9371
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
9372
|
+
const a = arrays[i];
|
|
9373
|
+
res.set(a, pad);
|
|
9374
|
+
pad += a.length;
|
|
9375
|
+
}
|
|
9376
|
+
return res;
|
|
9377
|
+
}
|
|
9190
9378
|
var Hash = class {
|
|
9191
9379
|
};
|
|
9192
|
-
function
|
|
9193
|
-
const hashC = (msg
|
|
9194
|
-
const tmp = hashCons(
|
|
9380
|
+
function createHasher(hashCons) {
|
|
9381
|
+
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
|
9382
|
+
const tmp = hashCons();
|
|
9195
9383
|
hashC.outputLen = tmp.outputLen;
|
|
9196
9384
|
hashC.blockLen = tmp.blockLen;
|
|
9197
|
-
hashC.create = (
|
|
9385
|
+
hashC.create = () => hashCons();
|
|
9198
9386
|
return hashC;
|
|
9199
9387
|
}
|
|
9200
|
-
|
|
9201
|
-
|
|
9202
|
-
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9207
|
-
|
|
9208
|
-
2600822924,
|
|
9209
|
-
528734635,
|
|
9210
|
-
1541459225
|
|
9211
|
-
]);
|
|
9212
|
-
|
|
9213
|
-
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/_u64.js
|
|
9214
|
-
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
9215
|
-
var _32n = /* @__PURE__ */ BigInt(32);
|
|
9216
|
-
function fromBig(n, le = false) {
|
|
9217
|
-
if (le)
|
|
9218
|
-
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
9219
|
-
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
9220
|
-
}
|
|
9221
|
-
|
|
9222
|
-
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/_blake.js
|
|
9223
|
-
function G1s(a, b, c, d, x) {
|
|
9224
|
-
a = a + b + x | 0;
|
|
9225
|
-
d = rotr(d ^ a, 16);
|
|
9226
|
-
c = c + d | 0;
|
|
9227
|
-
b = rotr(b ^ c, 12);
|
|
9228
|
-
return { a, b, c, d };
|
|
9229
|
-
}
|
|
9230
|
-
function G2s(a, b, c, d, x) {
|
|
9231
|
-
a = a + b + x | 0;
|
|
9232
|
-
d = rotr(d ^ a, 8);
|
|
9233
|
-
c = c + d | 0;
|
|
9234
|
-
b = rotr(b ^ c, 7);
|
|
9235
|
-
return { a, b, c, d };
|
|
9388
|
+
function randomBytes(bytesLength = 32) {
|
|
9389
|
+
if (crypto && typeof crypto.getRandomValues === "function") {
|
|
9390
|
+
return crypto.getRandomValues(new Uint8Array(bytesLength));
|
|
9391
|
+
}
|
|
9392
|
+
if (crypto && typeof crypto.randomBytes === "function") {
|
|
9393
|
+
return Uint8Array.from(crypto.randomBytes(bytesLength));
|
|
9394
|
+
}
|
|
9395
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
9236
9396
|
}
|
|
9237
9397
|
|
|
9238
|
-
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/
|
|
9239
|
-
|
|
9240
|
-
|
|
9398
|
+
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/_md.js
|
|
9399
|
+
function setBigUint64(view2, byteOffset, value, isLE) {
|
|
9400
|
+
if (typeof view2.setBigUint64 === "function")
|
|
9401
|
+
return view2.setBigUint64(byteOffset, value, isLE);
|
|
9402
|
+
const _32n2 = BigInt(32);
|
|
9403
|
+
const _u32_max = BigInt(4294967295);
|
|
9404
|
+
const wh = Number(value >> _32n2 & _u32_max);
|
|
9405
|
+
const wl = Number(value & _u32_max);
|
|
9406
|
+
const h = isLE ? 4 : 0;
|
|
9407
|
+
const l = isLE ? 0 : 4;
|
|
9408
|
+
view2.setUint32(byteOffset + h, wh, isLE);
|
|
9409
|
+
view2.setUint32(byteOffset + l, wl, isLE);
|
|
9410
|
+
}
|
|
9411
|
+
function Chi(a, b, c) {
|
|
9412
|
+
return a & b ^ ~a & c;
|
|
9413
|
+
}
|
|
9414
|
+
function Maj(a, b, c) {
|
|
9415
|
+
return a & b ^ a & c ^ b & c;
|
|
9416
|
+
}
|
|
9417
|
+
var HashMD = class extends Hash {
|
|
9418
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
9241
9419
|
super();
|
|
9242
9420
|
this.finished = false;
|
|
9243
|
-
this.destroyed = false;
|
|
9244
9421
|
this.length = 0;
|
|
9245
9422
|
this.pos = 0;
|
|
9246
|
-
|
|
9247
|
-
anumber(outputLen);
|
|
9423
|
+
this.destroyed = false;
|
|
9248
9424
|
this.blockLen = blockLen;
|
|
9249
9425
|
this.outputLen = outputLen;
|
|
9426
|
+
this.padOffset = padOffset;
|
|
9427
|
+
this.isLE = isLE;
|
|
9250
9428
|
this.buffer = new Uint8Array(blockLen);
|
|
9251
|
-
this.
|
|
9429
|
+
this.view = createView(this.buffer);
|
|
9252
9430
|
}
|
|
9253
9431
|
update(data) {
|
|
9254
9432
|
aexists(this);
|
|
9255
9433
|
data = toBytes(data);
|
|
9256
9434
|
abytes(data);
|
|
9257
|
-
const {
|
|
9435
|
+
const { view: view2, buffer, blockLen } = this;
|
|
9258
9436
|
const len = data.length;
|
|
9259
|
-
const offset = data.byteOffset;
|
|
9260
|
-
const buf = data.buffer;
|
|
9261
9437
|
for (let pos = 0; pos < len; ) {
|
|
9262
|
-
if (this.pos === blockLen) {
|
|
9263
|
-
swap32IfBE(buffer32);
|
|
9264
|
-
this.compress(buffer32, 0, false);
|
|
9265
|
-
swap32IfBE(buffer32);
|
|
9266
|
-
this.pos = 0;
|
|
9267
|
-
}
|
|
9268
9438
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) {
|
|
9274
|
-
this.length += blockLen;
|
|
9275
|
-
this.compress(data32, pos32, false);
|
|
9276
|
-
}
|
|
9277
|
-
swap32IfBE(data32);
|
|
9439
|
+
if (take === blockLen) {
|
|
9440
|
+
const dataView = createView(data);
|
|
9441
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
9442
|
+
this.process(dataView, pos);
|
|
9278
9443
|
continue;
|
|
9279
9444
|
}
|
|
9280
9445
|
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
9281
9446
|
this.pos += take;
|
|
9282
|
-
this.length += take;
|
|
9283
9447
|
pos += take;
|
|
9448
|
+
if (this.pos === blockLen) {
|
|
9449
|
+
this.process(view2, 0);
|
|
9450
|
+
this.pos = 0;
|
|
9451
|
+
}
|
|
9284
9452
|
}
|
|
9453
|
+
this.length += data.length;
|
|
9454
|
+
this.roundClean();
|
|
9285
9455
|
return this;
|
|
9286
9456
|
}
|
|
9287
9457
|
digestInto(out) {
|
|
9288
9458
|
aexists(this);
|
|
9289
9459
|
aoutput(out, this);
|
|
9290
|
-
const { pos, buffer32 } = this;
|
|
9291
9460
|
this.finished = true;
|
|
9461
|
+
const { buffer, view: view2, blockLen, isLE } = this;
|
|
9462
|
+
let { pos } = this;
|
|
9463
|
+
buffer[pos++] = 128;
|
|
9292
9464
|
clean(this.buffer.subarray(pos));
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9465
|
+
if (this.padOffset > blockLen - pos) {
|
|
9466
|
+
this.process(view2, 0);
|
|
9467
|
+
pos = 0;
|
|
9468
|
+
}
|
|
9469
|
+
for (let i = pos; i < blockLen; i++)
|
|
9470
|
+
buffer[i] = 0;
|
|
9471
|
+
setBigUint64(view2, blockLen - 8, BigInt(this.length * 8), isLE);
|
|
9472
|
+
this.process(view2, 0);
|
|
9473
|
+
const oview = createView(out);
|
|
9474
|
+
const len = this.outputLen;
|
|
9475
|
+
if (len % 4)
|
|
9476
|
+
throw new Error("_sha2: outputLen should be aligned to 32bit");
|
|
9477
|
+
const outLen = len / 4;
|
|
9478
|
+
const state = this.get();
|
|
9479
|
+
if (outLen > state.length)
|
|
9480
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
9481
|
+
for (let i = 0; i < outLen; i++)
|
|
9482
|
+
oview.setUint32(4 * i, state[i], isLE);
|
|
9298
9483
|
}
|
|
9299
9484
|
digest() {
|
|
9300
9485
|
const { buffer, outputLen } = this;
|
|
@@ -9304,1000 +9489,2502 @@ var BLAKE2 = class extends Hash {
|
|
|
9304
9489
|
return res;
|
|
9305
9490
|
}
|
|
9306
9491
|
_cloneInto(to) {
|
|
9307
|
-
|
|
9308
|
-
to || (to = new this.constructor({ dkLen: outputLen }));
|
|
9492
|
+
to || (to = new this.constructor());
|
|
9309
9493
|
to.set(...this.get());
|
|
9310
|
-
|
|
9494
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
9311
9495
|
to.destroyed = destroyed;
|
|
9312
9496
|
to.finished = finished;
|
|
9313
9497
|
to.length = length;
|
|
9314
9498
|
to.pos = pos;
|
|
9315
|
-
|
|
9499
|
+
if (length % blockLen)
|
|
9500
|
+
to.buffer.set(buffer);
|
|
9316
9501
|
return to;
|
|
9317
9502
|
}
|
|
9318
9503
|
clone() {
|
|
9319
9504
|
return this._cloneInto();
|
|
9320
9505
|
}
|
|
9321
9506
|
};
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
|
|
9507
|
+
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
9508
|
+
1779033703,
|
|
9509
|
+
3144134277,
|
|
9510
|
+
1013904242,
|
|
9511
|
+
2773480762,
|
|
9512
|
+
1359893119,
|
|
9513
|
+
2600822924,
|
|
9514
|
+
528734635,
|
|
9515
|
+
1541459225
|
|
9516
|
+
]);
|
|
9517
|
+
var SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
9518
|
+
1779033703,
|
|
9519
|
+
4089235720,
|
|
9520
|
+
3144134277,
|
|
9521
|
+
2227873595,
|
|
9522
|
+
1013904242,
|
|
9523
|
+
4271175723,
|
|
9524
|
+
2773480762,
|
|
9525
|
+
1595750129,
|
|
9526
|
+
1359893119,
|
|
9527
|
+
2917565137,
|
|
9528
|
+
2600822924,
|
|
9529
|
+
725511199,
|
|
9530
|
+
528734635,
|
|
9531
|
+
4215389547,
|
|
9532
|
+
1541459225,
|
|
9533
|
+
327033209
|
|
9534
|
+
]);
|
|
9535
|
+
|
|
9536
|
+
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/_u64.js
|
|
9537
|
+
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
9538
|
+
var _32n = /* @__PURE__ */ BigInt(32);
|
|
9539
|
+
function fromBig(n, le = false) {
|
|
9540
|
+
if (le)
|
|
9541
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
9542
|
+
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
9343
9543
|
}
|
|
9544
|
+
function split(lst, le = false) {
|
|
9545
|
+
const len = lst.length;
|
|
9546
|
+
let Ah = new Uint32Array(len);
|
|
9547
|
+
let Al = new Uint32Array(len);
|
|
9548
|
+
for (let i = 0; i < len; i++) {
|
|
9549
|
+
const { h, l } = fromBig(lst[i], le);
|
|
9550
|
+
[Ah[i], Al[i]] = [h, l];
|
|
9551
|
+
}
|
|
9552
|
+
return [Ah, Al];
|
|
9553
|
+
}
|
|
9554
|
+
var shrSH = (h, _l, s) => h >>> s;
|
|
9555
|
+
var shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
9556
|
+
var rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
9557
|
+
var rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
9558
|
+
var rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
9559
|
+
var rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
9560
|
+
function add(Ah, Al, Bh, Bl) {
|
|
9561
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
9562
|
+
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
9563
|
+
}
|
|
9564
|
+
var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
9565
|
+
var add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
9566
|
+
var add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
9567
|
+
var add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
9568
|
+
var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
9569
|
+
var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
9344
9570
|
|
|
9345
|
-
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/
|
|
9346
|
-
var
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9571
|
+
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/sha2.js
|
|
9572
|
+
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
9573
|
+
1116352408,
|
|
9574
|
+
1899447441,
|
|
9575
|
+
3049323471,
|
|
9576
|
+
3921009573,
|
|
9577
|
+
961987163,
|
|
9578
|
+
1508970993,
|
|
9579
|
+
2453635748,
|
|
9580
|
+
2870763221,
|
|
9581
|
+
3624381080,
|
|
9582
|
+
310598401,
|
|
9583
|
+
607225278,
|
|
9584
|
+
1426881987,
|
|
9585
|
+
1925078388,
|
|
9586
|
+
2162078206,
|
|
9587
|
+
2614888103,
|
|
9588
|
+
3248222580,
|
|
9589
|
+
3835390401,
|
|
9590
|
+
4022224774,
|
|
9591
|
+
264347078,
|
|
9592
|
+
604807628,
|
|
9593
|
+
770255983,
|
|
9594
|
+
1249150122,
|
|
9595
|
+
1555081692,
|
|
9596
|
+
1996064986,
|
|
9597
|
+
2554220882,
|
|
9598
|
+
2821834349,
|
|
9599
|
+
2952996808,
|
|
9600
|
+
3210313671,
|
|
9601
|
+
3336571891,
|
|
9602
|
+
3584528711,
|
|
9603
|
+
113926993,
|
|
9604
|
+
338241895,
|
|
9605
|
+
666307205,
|
|
9606
|
+
773529912,
|
|
9607
|
+
1294757372,
|
|
9608
|
+
1396182291,
|
|
9609
|
+
1695183700,
|
|
9610
|
+
1986661051,
|
|
9611
|
+
2177026350,
|
|
9612
|
+
2456956037,
|
|
9613
|
+
2730485921,
|
|
9614
|
+
2820302411,
|
|
9615
|
+
3259730800,
|
|
9616
|
+
3345764771,
|
|
9617
|
+
3516065817,
|
|
9618
|
+
3600352804,
|
|
9619
|
+
4094571909,
|
|
9620
|
+
275423344,
|
|
9621
|
+
430227734,
|
|
9622
|
+
506948616,
|
|
9623
|
+
659060556,
|
|
9624
|
+
883997877,
|
|
9625
|
+
958139571,
|
|
9626
|
+
1322822218,
|
|
9627
|
+
1537002063,
|
|
9628
|
+
1747873779,
|
|
9629
|
+
1955562222,
|
|
9630
|
+
2024104815,
|
|
9631
|
+
2227730452,
|
|
9632
|
+
2361852424,
|
|
9633
|
+
2428436474,
|
|
9634
|
+
2756734187,
|
|
9635
|
+
3204031479,
|
|
9636
|
+
3329325298
|
|
9637
|
+
]);
|
|
9638
|
+
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
9639
|
+
var SHA256 = class extends HashMD {
|
|
9640
|
+
constructor(outputLen = 32) {
|
|
9641
|
+
super(64, outputLen, 8, false);
|
|
9642
|
+
this.A = SHA256_IV[0] | 0;
|
|
9643
|
+
this.B = SHA256_IV[1] | 0;
|
|
9644
|
+
this.C = SHA256_IV[2] | 0;
|
|
9645
|
+
this.D = SHA256_IV[3] | 0;
|
|
9646
|
+
this.E = SHA256_IV[4] | 0;
|
|
9647
|
+
this.F = SHA256_IV[5] | 0;
|
|
9648
|
+
this.G = SHA256_IV[6] | 0;
|
|
9649
|
+
this.H = SHA256_IV[7] | 0;
|
|
9397
9650
|
}
|
|
9398
|
-
// Unused
|
|
9399
9651
|
get() {
|
|
9400
|
-
|
|
9652
|
+
const { A, B, C, D, E, F, G, H } = this;
|
|
9653
|
+
return [A, B, C, D, E, F, G, H];
|
|
9654
|
+
}
|
|
9655
|
+
// prettier-ignore
|
|
9656
|
+
set(A, B, C, D, E, F, G, H) {
|
|
9657
|
+
this.A = A | 0;
|
|
9658
|
+
this.B = B | 0;
|
|
9659
|
+
this.C = C | 0;
|
|
9660
|
+
this.D = D | 0;
|
|
9661
|
+
this.E = E | 0;
|
|
9662
|
+
this.F = F | 0;
|
|
9663
|
+
this.G = G | 0;
|
|
9664
|
+
this.H = H | 0;
|
|
9665
|
+
}
|
|
9666
|
+
process(view2, offset) {
|
|
9667
|
+
for (let i = 0; i < 16; i++, offset += 4)
|
|
9668
|
+
SHA256_W[i] = view2.getUint32(offset, false);
|
|
9669
|
+
for (let i = 16; i < 64; i++) {
|
|
9670
|
+
const W15 = SHA256_W[i - 15];
|
|
9671
|
+
const W2 = SHA256_W[i - 2];
|
|
9672
|
+
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
9673
|
+
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
9674
|
+
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
9675
|
+
}
|
|
9676
|
+
let { A, B, C, D, E, F, G, H } = this;
|
|
9677
|
+
for (let i = 0; i < 64; i++) {
|
|
9678
|
+
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
9679
|
+
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
|
|
9680
|
+
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
9681
|
+
const T2 = sigma0 + Maj(A, B, C) | 0;
|
|
9682
|
+
H = G;
|
|
9683
|
+
G = F;
|
|
9684
|
+
F = E;
|
|
9685
|
+
E = D + T1 | 0;
|
|
9686
|
+
D = C;
|
|
9687
|
+
C = B;
|
|
9688
|
+
B = A;
|
|
9689
|
+
A = T1 + T2 | 0;
|
|
9690
|
+
}
|
|
9691
|
+
A = A + this.A | 0;
|
|
9692
|
+
B = B + this.B | 0;
|
|
9693
|
+
C = C + this.C | 0;
|
|
9694
|
+
D = D + this.D | 0;
|
|
9695
|
+
E = E + this.E | 0;
|
|
9696
|
+
F = F + this.F | 0;
|
|
9697
|
+
G = G + this.G | 0;
|
|
9698
|
+
H = H + this.H | 0;
|
|
9699
|
+
this.set(A, B, C, D, E, F, G, H);
|
|
9700
|
+
}
|
|
9701
|
+
roundClean() {
|
|
9702
|
+
clean(SHA256_W);
|
|
9401
9703
|
}
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
const { state: s, pos } = this;
|
|
9406
|
-
const { h, l } = fromBig(BigInt(counter), true);
|
|
9407
|
-
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, bufPos, buf, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], h, l, pos, flags);
|
|
9408
|
-
s[0] = v0 ^ v8;
|
|
9409
|
-
s[1] = v1 ^ v9;
|
|
9410
|
-
s[2] = v2 ^ v10;
|
|
9411
|
-
s[3] = v3 ^ v11;
|
|
9412
|
-
s[4] = v4 ^ v12;
|
|
9413
|
-
s[5] = v5 ^ v13;
|
|
9414
|
-
s[6] = v6 ^ v14;
|
|
9415
|
-
s[7] = v7 ^ v15;
|
|
9416
|
-
}
|
|
9417
|
-
compress(buf, bufPos = 0, isLast = false) {
|
|
9418
|
-
let flags = this.flags;
|
|
9419
|
-
if (!this.chunkPos)
|
|
9420
|
-
flags |= B3_Flags.CHUNK_START;
|
|
9421
|
-
if (this.chunkPos === 15 || isLast)
|
|
9422
|
-
flags |= B3_Flags.CHUNK_END;
|
|
9423
|
-
if (!isLast)
|
|
9424
|
-
this.pos = this.blockLen;
|
|
9425
|
-
this.b2Compress(this.chunksDone, flags, buf, bufPos);
|
|
9426
|
-
this.chunkPos += 1;
|
|
9427
|
-
if (this.chunkPos === 16 || isLast) {
|
|
9428
|
-
let chunk = this.state;
|
|
9429
|
-
this.state = this.IV.slice();
|
|
9430
|
-
for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) {
|
|
9431
|
-
if (!(last = this.stack.pop()))
|
|
9432
|
-
break;
|
|
9433
|
-
this.buffer32.set(last, 0);
|
|
9434
|
-
this.buffer32.set(chunk, 8);
|
|
9435
|
-
this.pos = this.blockLen;
|
|
9436
|
-
this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0);
|
|
9437
|
-
chunk = this.state;
|
|
9438
|
-
this.state = this.IV.slice();
|
|
9439
|
-
}
|
|
9440
|
-
this.chunksDone++;
|
|
9441
|
-
this.chunkPos = 0;
|
|
9442
|
-
this.stack.push(chunk);
|
|
9443
|
-
}
|
|
9444
|
-
this.pos = 0;
|
|
9704
|
+
destroy() {
|
|
9705
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
9706
|
+
clean(this.buffer);
|
|
9445
9707
|
}
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9708
|
+
};
|
|
9709
|
+
var K512 = /* @__PURE__ */ (() => split([
|
|
9710
|
+
"0x428a2f98d728ae22",
|
|
9711
|
+
"0x7137449123ef65cd",
|
|
9712
|
+
"0xb5c0fbcfec4d3b2f",
|
|
9713
|
+
"0xe9b5dba58189dbbc",
|
|
9714
|
+
"0x3956c25bf348b538",
|
|
9715
|
+
"0x59f111f1b605d019",
|
|
9716
|
+
"0x923f82a4af194f9b",
|
|
9717
|
+
"0xab1c5ed5da6d8118",
|
|
9718
|
+
"0xd807aa98a3030242",
|
|
9719
|
+
"0x12835b0145706fbe",
|
|
9720
|
+
"0x243185be4ee4b28c",
|
|
9721
|
+
"0x550c7dc3d5ffb4e2",
|
|
9722
|
+
"0x72be5d74f27b896f",
|
|
9723
|
+
"0x80deb1fe3b1696b1",
|
|
9724
|
+
"0x9bdc06a725c71235",
|
|
9725
|
+
"0xc19bf174cf692694",
|
|
9726
|
+
"0xe49b69c19ef14ad2",
|
|
9727
|
+
"0xefbe4786384f25e3",
|
|
9728
|
+
"0x0fc19dc68b8cd5b5",
|
|
9729
|
+
"0x240ca1cc77ac9c65",
|
|
9730
|
+
"0x2de92c6f592b0275",
|
|
9731
|
+
"0x4a7484aa6ea6e483",
|
|
9732
|
+
"0x5cb0a9dcbd41fbd4",
|
|
9733
|
+
"0x76f988da831153b5",
|
|
9734
|
+
"0x983e5152ee66dfab",
|
|
9735
|
+
"0xa831c66d2db43210",
|
|
9736
|
+
"0xb00327c898fb213f",
|
|
9737
|
+
"0xbf597fc7beef0ee4",
|
|
9738
|
+
"0xc6e00bf33da88fc2",
|
|
9739
|
+
"0xd5a79147930aa725",
|
|
9740
|
+
"0x06ca6351e003826f",
|
|
9741
|
+
"0x142929670a0e6e70",
|
|
9742
|
+
"0x27b70a8546d22ffc",
|
|
9743
|
+
"0x2e1b21385c26c926",
|
|
9744
|
+
"0x4d2c6dfc5ac42aed",
|
|
9745
|
+
"0x53380d139d95b3df",
|
|
9746
|
+
"0x650a73548baf63de",
|
|
9747
|
+
"0x766a0abb3c77b2a8",
|
|
9748
|
+
"0x81c2c92e47edaee6",
|
|
9749
|
+
"0x92722c851482353b",
|
|
9750
|
+
"0xa2bfe8a14cf10364",
|
|
9751
|
+
"0xa81a664bbc423001",
|
|
9752
|
+
"0xc24b8b70d0f89791",
|
|
9753
|
+
"0xc76c51a30654be30",
|
|
9754
|
+
"0xd192e819d6ef5218",
|
|
9755
|
+
"0xd69906245565a910",
|
|
9756
|
+
"0xf40e35855771202a",
|
|
9757
|
+
"0x106aa07032bbd1b8",
|
|
9758
|
+
"0x19a4c116b8d2d0c8",
|
|
9759
|
+
"0x1e376c085141ab53",
|
|
9760
|
+
"0x2748774cdf8eeb99",
|
|
9761
|
+
"0x34b0bcb5e19b48a8",
|
|
9762
|
+
"0x391c0cb3c5c95a63",
|
|
9763
|
+
"0x4ed8aa4ae3418acb",
|
|
9764
|
+
"0x5b9cca4f7763e373",
|
|
9765
|
+
"0x682e6ff3d6b2b8a3",
|
|
9766
|
+
"0x748f82ee5defb2fc",
|
|
9767
|
+
"0x78a5636f43172f60",
|
|
9768
|
+
"0x84c87814a1f0ab72",
|
|
9769
|
+
"0x8cc702081a6439ec",
|
|
9770
|
+
"0x90befffa23631e28",
|
|
9771
|
+
"0xa4506cebde82bde9",
|
|
9772
|
+
"0xbef9a3f7b2c67915",
|
|
9773
|
+
"0xc67178f2e372532b",
|
|
9774
|
+
"0xca273eceea26619c",
|
|
9775
|
+
"0xd186b8c721c0c207",
|
|
9776
|
+
"0xeada7dd6cde0eb1e",
|
|
9777
|
+
"0xf57d4f7fee6ed178",
|
|
9778
|
+
"0x06f067aa72176fba",
|
|
9779
|
+
"0x0a637dc5a2c898a6",
|
|
9780
|
+
"0x113f9804bef90dae",
|
|
9781
|
+
"0x1b710b35131c471b",
|
|
9782
|
+
"0x28db77f523047d84",
|
|
9783
|
+
"0x32caab7b40c72493",
|
|
9784
|
+
"0x3c9ebe0a15c9bebc",
|
|
9785
|
+
"0x431d67c49c100d4c",
|
|
9786
|
+
"0x4cc5d4becb3e42b6",
|
|
9787
|
+
"0x597f299cfc657e2a",
|
|
9788
|
+
"0x5fcb6fab3ad6faec",
|
|
9789
|
+
"0x6c44198c4a475817"
|
|
9790
|
+
].map((n) => BigInt(n))))();
|
|
9791
|
+
var SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
|
9792
|
+
var SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
9793
|
+
var SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
9794
|
+
var SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
9795
|
+
var SHA512 = class extends HashMD {
|
|
9796
|
+
constructor(outputLen = 64) {
|
|
9797
|
+
super(128, outputLen, 16, false);
|
|
9798
|
+
this.Ah = SHA512_IV[0] | 0;
|
|
9799
|
+
this.Al = SHA512_IV[1] | 0;
|
|
9800
|
+
this.Bh = SHA512_IV[2] | 0;
|
|
9801
|
+
this.Bl = SHA512_IV[3] | 0;
|
|
9802
|
+
this.Ch = SHA512_IV[4] | 0;
|
|
9803
|
+
this.Cl = SHA512_IV[5] | 0;
|
|
9804
|
+
this.Dh = SHA512_IV[6] | 0;
|
|
9805
|
+
this.Dl = SHA512_IV[7] | 0;
|
|
9806
|
+
this.Eh = SHA512_IV[8] | 0;
|
|
9807
|
+
this.El = SHA512_IV[9] | 0;
|
|
9808
|
+
this.Fh = SHA512_IV[10] | 0;
|
|
9809
|
+
this.Fl = SHA512_IV[11] | 0;
|
|
9810
|
+
this.Gh = SHA512_IV[12] | 0;
|
|
9811
|
+
this.Gl = SHA512_IV[13] | 0;
|
|
9812
|
+
this.Hh = SHA512_IV[14] | 0;
|
|
9813
|
+
this.Hl = SHA512_IV[15] | 0;
|
|
9814
|
+
}
|
|
9815
|
+
// prettier-ignore
|
|
9816
|
+
get() {
|
|
9817
|
+
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
9818
|
+
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
|
9819
|
+
}
|
|
9820
|
+
// prettier-ignore
|
|
9821
|
+
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
|
9822
|
+
this.Ah = Ah | 0;
|
|
9823
|
+
this.Al = Al | 0;
|
|
9824
|
+
this.Bh = Bh | 0;
|
|
9825
|
+
this.Bl = Bl | 0;
|
|
9826
|
+
this.Ch = Ch | 0;
|
|
9827
|
+
this.Cl = Cl | 0;
|
|
9828
|
+
this.Dh = Dh | 0;
|
|
9829
|
+
this.Dl = Dl | 0;
|
|
9830
|
+
this.Eh = Eh | 0;
|
|
9831
|
+
this.El = El | 0;
|
|
9832
|
+
this.Fh = Fh | 0;
|
|
9833
|
+
this.Fl = Fl | 0;
|
|
9834
|
+
this.Gh = Gh | 0;
|
|
9835
|
+
this.Gl = Gl | 0;
|
|
9836
|
+
this.Hh = Hh | 0;
|
|
9837
|
+
this.Hl = Hl | 0;
|
|
9838
|
+
}
|
|
9839
|
+
process(view2, offset) {
|
|
9840
|
+
for (let i = 0; i < 16; i++, offset += 4) {
|
|
9841
|
+
SHA512_W_H[i] = view2.getUint32(offset);
|
|
9842
|
+
SHA512_W_L[i] = view2.getUint32(offset += 4);
|
|
9843
|
+
}
|
|
9844
|
+
for (let i = 16; i < 80; i++) {
|
|
9845
|
+
const W15h = SHA512_W_H[i - 15] | 0;
|
|
9846
|
+
const W15l = SHA512_W_L[i - 15] | 0;
|
|
9847
|
+
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
9848
|
+
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
9849
|
+
const W2h = SHA512_W_H[i - 2] | 0;
|
|
9850
|
+
const W2l = SHA512_W_L[i - 2] | 0;
|
|
9851
|
+
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
9852
|
+
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
9853
|
+
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
9854
|
+
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
|
9855
|
+
SHA512_W_H[i] = SUMh | 0;
|
|
9856
|
+
SHA512_W_L[i] = SUMl | 0;
|
|
9857
|
+
}
|
|
9858
|
+
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
9859
|
+
for (let i = 0; i < 80; i++) {
|
|
9860
|
+
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
9861
|
+
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
9862
|
+
const CHIh = Eh & Fh ^ ~Eh & Gh;
|
|
9863
|
+
const CHIl = El & Fl ^ ~El & Gl;
|
|
9864
|
+
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
9865
|
+
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
9866
|
+
const T1l = T1ll | 0;
|
|
9867
|
+
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
9868
|
+
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
9869
|
+
const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
|
|
9870
|
+
const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
|
|
9871
|
+
Hh = Gh | 0;
|
|
9872
|
+
Hl = Gl | 0;
|
|
9873
|
+
Gh = Fh | 0;
|
|
9874
|
+
Gl = Fl | 0;
|
|
9875
|
+
Fh = Eh | 0;
|
|
9876
|
+
Fl = El | 0;
|
|
9877
|
+
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
9878
|
+
Dh = Ch | 0;
|
|
9879
|
+
Dl = Cl | 0;
|
|
9880
|
+
Ch = Bh | 0;
|
|
9881
|
+
Cl = Bl | 0;
|
|
9882
|
+
Bh = Ah | 0;
|
|
9883
|
+
Bl = Al | 0;
|
|
9884
|
+
const All = add3L(T1l, sigma0l, MAJl);
|
|
9885
|
+
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
9886
|
+
Al = All | 0;
|
|
9887
|
+
}
|
|
9888
|
+
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
9889
|
+
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
9890
|
+
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
9891
|
+
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
9892
|
+
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
9893
|
+
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
9894
|
+
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
9895
|
+
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
9896
|
+
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
9897
|
+
}
|
|
9898
|
+
roundClean() {
|
|
9899
|
+
clean(SHA512_W_H, SHA512_W_L);
|
|
9460
9900
|
}
|
|
9461
9901
|
destroy() {
|
|
9462
|
-
this.
|
|
9463
|
-
|
|
9464
|
-
clean(...this.stack);
|
|
9465
|
-
}
|
|
9466
|
-
// Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8)
|
|
9467
|
-
b2CompressOut() {
|
|
9468
|
-
const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this;
|
|
9469
|
-
const { h, l } = fromBig(BigInt(this.chunkOut++));
|
|
9470
|
-
swap32IfBE(buffer32);
|
|
9471
|
-
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress(B3_SIGMA, 0, buffer32, 7, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags);
|
|
9472
|
-
out32[0] = v0 ^ v8;
|
|
9473
|
-
out32[1] = v1 ^ v9;
|
|
9474
|
-
out32[2] = v2 ^ v10;
|
|
9475
|
-
out32[3] = v3 ^ v11;
|
|
9476
|
-
out32[4] = v4 ^ v12;
|
|
9477
|
-
out32[5] = v5 ^ v13;
|
|
9478
|
-
out32[6] = v6 ^ v14;
|
|
9479
|
-
out32[7] = v7 ^ v15;
|
|
9480
|
-
out32[8] = s[0] ^ v8;
|
|
9481
|
-
out32[9] = s[1] ^ v9;
|
|
9482
|
-
out32[10] = s[2] ^ v10;
|
|
9483
|
-
out32[11] = s[3] ^ v11;
|
|
9484
|
-
out32[12] = s[4] ^ v12;
|
|
9485
|
-
out32[13] = s[5] ^ v13;
|
|
9486
|
-
out32[14] = s[6] ^ v14;
|
|
9487
|
-
out32[15] = s[7] ^ v15;
|
|
9488
|
-
swap32IfBE(buffer32);
|
|
9489
|
-
swap32IfBE(out32);
|
|
9490
|
-
this.posOut = 0;
|
|
9491
|
-
}
|
|
9492
|
-
finish() {
|
|
9493
|
-
if (this.finished)
|
|
9494
|
-
return;
|
|
9495
|
-
this.finished = true;
|
|
9496
|
-
clean(this.buffer.subarray(this.pos));
|
|
9497
|
-
let flags = this.flags | B3_Flags.ROOT;
|
|
9498
|
-
if (this.stack.length) {
|
|
9499
|
-
flags |= B3_Flags.PARENT;
|
|
9500
|
-
swap32IfBE(this.buffer32);
|
|
9501
|
-
this.compress(this.buffer32, 0, true);
|
|
9502
|
-
swap32IfBE(this.buffer32);
|
|
9503
|
-
this.chunksDone = 0;
|
|
9504
|
-
this.pos = this.blockLen;
|
|
9505
|
-
} else {
|
|
9506
|
-
flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END;
|
|
9507
|
-
}
|
|
9508
|
-
this.flags = flags;
|
|
9509
|
-
this.b2CompressOut();
|
|
9510
|
-
}
|
|
9511
|
-
writeInto(out) {
|
|
9512
|
-
aexists(this, false);
|
|
9513
|
-
abytes(out);
|
|
9514
|
-
this.finish();
|
|
9515
|
-
const { blockLen, bufferOut } = this;
|
|
9516
|
-
for (let pos = 0, len = out.length; pos < len; ) {
|
|
9517
|
-
if (this.posOut >= blockLen)
|
|
9518
|
-
this.b2CompressOut();
|
|
9519
|
-
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
9520
|
-
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
9521
|
-
this.posOut += take;
|
|
9522
|
-
pos += take;
|
|
9523
|
-
}
|
|
9524
|
-
return out;
|
|
9902
|
+
clean(this.buffer);
|
|
9903
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
9525
9904
|
}
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9905
|
+
};
|
|
9906
|
+
var sha256 = /* @__PURE__ */ createHasher(() => new SHA256());
|
|
9907
|
+
var sha512 = /* @__PURE__ */ createHasher(() => new SHA512());
|
|
9908
|
+
|
|
9909
|
+
// ../mmt-manifest-verify/node_modules/@noble/hashes/esm/sha256.js
|
|
9910
|
+
var sha2562 = sha256;
|
|
9911
|
+
|
|
9912
|
+
// ../mmt-manifest-verify/dist/bc-provenance-v2.js
|
|
9913
|
+
var BCPV2_HEADER_LENGTH = 68;
|
|
9914
|
+
var BCPV2_SIGNATURE_LENGTH = 64;
|
|
9915
|
+
var BCPV2_MIN_RECORD_LENGTH = BCPV2_HEADER_LENGTH + 32 + BCPV2_SIGNATURE_LENGTH;
|
|
9916
|
+
var BCPV2_MAX_RECORD_LENGTH = 1316;
|
|
9917
|
+
var BCPV2_MAX_DIGESTS = 37;
|
|
9918
|
+
var BCPV2_HASH_ALG_SHA256 = 1;
|
|
9919
|
+
var text = new TextEncoder();
|
|
9920
|
+
var MAGIC = Uint8Array.from([77, 72, 77, 50]);
|
|
9921
|
+
var SIGNING_DOMAIN = text.encode("mcast-manifest-v2\0");
|
|
9922
|
+
function equalBytes(left, right) {
|
|
9923
|
+
if (left.byteLength !== right.byteLength)
|
|
9924
|
+
return false;
|
|
9925
|
+
let different = 0;
|
|
9926
|
+
for (let index = 0; index < left.byteLength; index++)
|
|
9927
|
+
different |= left[index] ^ right[index];
|
|
9928
|
+
return different === 0;
|
|
9929
|
+
}
|
|
9930
|
+
function u16(value) {
|
|
9931
|
+
const result = new Uint8Array(2);
|
|
9932
|
+
new DataView(result.buffer).setUint16(0, value);
|
|
9933
|
+
return result;
|
|
9934
|
+
}
|
|
9935
|
+
function u322(value) {
|
|
9936
|
+
const result = new Uint8Array(4);
|
|
9937
|
+
new DataView(result.buffer).setUint32(0, value);
|
|
9938
|
+
return result;
|
|
9939
|
+
}
|
|
9940
|
+
function validU32(value) {
|
|
9941
|
+
return Number.isInteger(value) && value >= 0 && value <= 4294967295;
|
|
9942
|
+
}
|
|
9943
|
+
function validPort(value) {
|
|
9944
|
+
return Number.isInteger(value) && value >= 0 && value <= 65535;
|
|
9945
|
+
}
|
|
9946
|
+
function parseIpv4(address) {
|
|
9947
|
+
const fields = address.split(".");
|
|
9948
|
+
if (fields.length !== 4 || fields.some((field) => !/^\d+$/.test(field))) {
|
|
9949
|
+
throw new Error(`invalid IPv4 address ${address}`);
|
|
9950
|
+
}
|
|
9951
|
+
const values = fields.map(Number);
|
|
9952
|
+
if (values.some((value, index) => value > 255 || String(value) !== fields[index])) {
|
|
9953
|
+
throw new Error(`invalid IPv4 address ${address}`);
|
|
9954
|
+
}
|
|
9955
|
+
return Uint8Array.from(values);
|
|
9956
|
+
}
|
|
9957
|
+
function parseIpv6(address) {
|
|
9958
|
+
const compressed = address.includes("::");
|
|
9959
|
+
if ((address.match(/::/g) ?? []).length > 1)
|
|
9960
|
+
throw new Error(`invalid IPv6 address ${address}`);
|
|
9961
|
+
const [leftText, rightText = ""] = address.split("::");
|
|
9962
|
+
const left = leftText ? leftText.split(":") : [];
|
|
9963
|
+
const right = rightText ? rightText.split(":") : [];
|
|
9964
|
+
if (left.some((group) => group.includes(".")) || right.some((group) => group.includes("."))) {
|
|
9965
|
+
throw new Error(`invalid IPv6 address ${address}`);
|
|
9966
|
+
}
|
|
9967
|
+
const missing = 8 - left.length - right.length;
|
|
9968
|
+
if (missing < 0 || !compressed && missing !== 0 || compressed && missing < 1) {
|
|
9969
|
+
throw new Error(`invalid IPv6 address ${address}`);
|
|
9970
|
+
}
|
|
9971
|
+
const groups = [...left, ...Array.from({ length: missing }, () => "0"), ...right];
|
|
9972
|
+
if (groups.length !== 8 || groups.some((group) => !/^[0-9a-f]{1,4}$/i.test(group))) {
|
|
9973
|
+
throw new Error(`invalid IPv6 address ${address}`);
|
|
9974
|
+
}
|
|
9975
|
+
const result = new Uint8Array(16);
|
|
9976
|
+
const view2 = new DataView(result.buffer);
|
|
9977
|
+
groups.forEach((group, index) => view2.setUint16(index * 2, Number.parseInt(group, 16)));
|
|
9978
|
+
return result;
|
|
9979
|
+
}
|
|
9980
|
+
function parseBcProvenanceV2Address(address) {
|
|
9981
|
+
if (address.includes(":"))
|
|
9982
|
+
return parseIpv6(address);
|
|
9983
|
+
return parseIpv4(address);
|
|
9984
|
+
}
|
|
9985
|
+
function endpointBytes(endpoint) {
|
|
9986
|
+
if (!validPort(endpoint.port) || !validPort(endpoint.manifestPort) || !validU32(endpoint.streamId)) {
|
|
9987
|
+
throw new Error("invalid BCPV2 endpoint");
|
|
9530
9988
|
}
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9989
|
+
const source = parseBcProvenanceV2Address(endpoint.sourceAddress);
|
|
9990
|
+
const group = parseBcProvenanceV2Address(endpoint.groupAddress);
|
|
9991
|
+
if (source.byteLength !== group.byteLength)
|
|
9992
|
+
throw new Error("endpoint address families differ");
|
|
9993
|
+
return { source, group };
|
|
9994
|
+
}
|
|
9995
|
+
function readU32(view2, offset) {
|
|
9996
|
+
return view2.getUint32(offset);
|
|
9997
|
+
}
|
|
9998
|
+
function readU642(view2, offset) {
|
|
9999
|
+
return view2.getBigUint64(offset);
|
|
10000
|
+
}
|
|
10001
|
+
function decodeBcProvenanceV2Record(input) {
|
|
10002
|
+
const bytes = Uint8Array.from(input);
|
|
10003
|
+
if (bytes.byteLength < BCPV2_MIN_RECORD_LENGTH || bytes.byteLength > BCPV2_MAX_RECORD_LENGTH || (bytes.byteLength - 132) % 32 !== 0) {
|
|
10004
|
+
throw new Error("invalid BCPV2 record length");
|
|
9534
10005
|
}
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9539
|
-
|
|
9540
|
-
|
|
9541
|
-
this.destroy();
|
|
9542
|
-
return out;
|
|
10006
|
+
const view2 = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
10007
|
+
if (!equalBytes(bytes.subarray(0, 4), MAGIC))
|
|
10008
|
+
throw new Error("invalid BCPV2 record magic");
|
|
10009
|
+
const count = view2.getUint16(28);
|
|
10010
|
+
if (count < 1 || count > BCPV2_MAX_DIGESTS || bytes.byteLength !== 132 + count * 32) {
|
|
10011
|
+
throw new Error("invalid BCPV2 record count");
|
|
9543
10012
|
}
|
|
9544
|
-
|
|
9545
|
-
|
|
10013
|
+
const body = bytes.slice(0, bytes.byteLength - BCPV2_SIGNATURE_LENGTH);
|
|
10014
|
+
const digests = [];
|
|
10015
|
+
for (let index = 0; index < count; index++) {
|
|
10016
|
+
digests.push(bytes.slice(BCPV2_HEADER_LENGTH + index * 32, BCPV2_HEADER_LENGTH + (index + 1) * 32));
|
|
9546
10017
|
}
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
if (value.byteLength !== length) {
|
|
9562
|
-
throw new Error(`${name} must be ${length} bytes, got ${value.byteLength}`);
|
|
9563
|
-
}
|
|
9564
|
-
}
|
|
9565
|
-
function requireU32(name, value) {
|
|
9566
|
-
if (!Number.isInteger(value) || value < 0 || value > 4294967295) {
|
|
9567
|
-
throw new Error(`${name} must be an unsigned 32-bit integer`);
|
|
9568
|
-
}
|
|
9569
|
-
}
|
|
9570
|
-
function requireU64(name, value) {
|
|
9571
|
-
if (value < 0n || value > 0xffffffffffffffffn) {
|
|
9572
|
-
throw new Error(`${name} must be an unsigned 64-bit integer`);
|
|
9573
|
-
}
|
|
9574
|
-
}
|
|
9575
|
-
function requireTrueLength(value) {
|
|
9576
|
-
requireU32("trueLength", value);
|
|
9577
|
-
if (value > SOURCE_AUTH_MAX_TRUE_LENGTH) {
|
|
9578
|
-
throw new Error(`trueLength exceeds the ${SOURCE_AUTH_MAX_TRUE_LENGTH}-byte profile maximum`);
|
|
9579
|
-
}
|
|
9580
|
-
}
|
|
9581
|
-
function sourceAuthObjectDigest(object) {
|
|
9582
|
-
return blake3(object);
|
|
9583
|
-
}
|
|
9584
|
-
function sourceAuthLeafHash(groupId, objectId, digest, trueLength) {
|
|
9585
|
-
requireU64("groupId", groupId);
|
|
9586
|
-
requireU32("objectId", objectId);
|
|
9587
|
-
requireBytes("digest", digest, 32);
|
|
9588
|
-
requireTrueLength(trueLength);
|
|
9589
|
-
const preimage = new Uint8Array(49);
|
|
9590
|
-
const view2 = new DataView(preimage.buffer);
|
|
9591
|
-
view2.setBigUint64(1, groupId);
|
|
9592
|
-
view2.setUint32(9, objectId);
|
|
9593
|
-
preimage.set(digest, 13);
|
|
9594
|
-
view2.setUint32(45, trueLength);
|
|
9595
|
-
return blake3(preimage);
|
|
9596
|
-
}
|
|
9597
|
-
function sourceAuthMerkleRoot(entries) {
|
|
9598
|
-
if (entries.length === 0)
|
|
9599
|
-
throw new Error("Merkle tree requires at least one object");
|
|
9600
|
-
if (entries.length > SOURCE_AUTH_MAX_OBJECTS_PER_GROUP) {
|
|
9601
|
-
throw new Error(`group exceeds ${SOURCE_AUTH_MAX_OBJECTS_PER_GROUP} objects`);
|
|
9602
|
-
}
|
|
9603
|
-
const groupId = entries[0].groupId;
|
|
9604
|
-
const objectIds = /* @__PURE__ */ new Set();
|
|
9605
|
-
const ordered = [...entries].sort((left, right) => left.objectId - right.objectId);
|
|
9606
|
-
let level = ordered.map((entry) => {
|
|
9607
|
-
if (entry.groupId !== groupId)
|
|
9608
|
-
throw new Error("Merkle entries must belong to one group");
|
|
9609
|
-
if (objectIds.has(entry.objectId))
|
|
9610
|
-
throw new Error(`duplicate objectId ${entry.objectId}`);
|
|
9611
|
-
objectIds.add(entry.objectId);
|
|
9612
|
-
return sourceAuthLeafHash(entry.groupId, entry.objectId, entry.digest, entry.trueLength);
|
|
9613
|
-
});
|
|
9614
|
-
while (level.length > 1) {
|
|
9615
|
-
const parents = [];
|
|
9616
|
-
for (let index = 0; index < level.length; index += 2) {
|
|
9617
|
-
const left = level[index];
|
|
9618
|
-
const right = level[index + 1] ?? left;
|
|
9619
|
-
const preimage = new Uint8Array(65);
|
|
9620
|
-
preimage[0] = 1;
|
|
9621
|
-
preimage.set(left, 1);
|
|
9622
|
-
preimage.set(right, 33);
|
|
9623
|
-
parents.push(blake3(preimage));
|
|
9624
|
-
}
|
|
9625
|
-
level = parents;
|
|
9626
|
-
}
|
|
9627
|
-
return level[0];
|
|
9628
|
-
}
|
|
9629
|
-
function sourceAuthSignaturePreimage(authScope, groupId, objectCount, root) {
|
|
9630
|
-
requireU32("objectCount", objectCount);
|
|
9631
|
-
if (objectCount === 0 || objectCount > SOURCE_AUTH_MAX_OBJECTS_PER_GROUP) {
|
|
9632
|
-
throw new Error(`objectCount must be between 1 and ${SOURCE_AUTH_MAX_OBJECTS_PER_GROUP}`);
|
|
9633
|
-
}
|
|
9634
|
-
requireU64("groupId", groupId);
|
|
9635
|
-
requireBytes("authScope", authScope, SOURCE_AUTH_SCOPE_LENGTH);
|
|
9636
|
-
requireBytes("root", root, 32);
|
|
9637
|
-
const preimage = new Uint8Array(100);
|
|
9638
|
-
const view2 = new DataView(preimage.buffer);
|
|
9639
|
-
preimage.set(SIGNATURE_DOMAIN);
|
|
9640
|
-
preimage.set(authScope, 24);
|
|
9641
|
-
view2.setBigUint64(56, groupId);
|
|
9642
|
-
view2.setUint32(64, objectCount);
|
|
9643
|
-
preimage.set(root, 68);
|
|
9644
|
-
return preimage;
|
|
9645
|
-
}
|
|
9646
|
-
function decodeSourceAuthManifestFrame(frame) {
|
|
9647
|
-
const frameType = frame[0];
|
|
9648
|
-
const expectedLength = frameType === SOURCE_AUTH_OBJECT_ENTRY_FRAME ? SOURCE_AUTH_OBJECT_ENTRY_LENGTH : frameType === SOURCE_AUTH_GROUP_CLOSE_FRAME ? SOURCE_AUTH_GROUP_CLOSE_LENGTH : 0;
|
|
9649
|
-
if (expectedLength === 0)
|
|
9650
|
-
throw new Error(`unsupported manifest frame type ${frameType}`);
|
|
9651
|
-
if (frame.byteLength !== expectedLength) {
|
|
9652
|
-
throw new Error(`manifest frame has invalid length ${frame.byteLength} for type ${frameType}`);
|
|
9653
|
-
}
|
|
9654
|
-
if (frame[1] !== SOURCE_AUTH_MANIFEST_VERSION) {
|
|
9655
|
-
throw new Error(`unsupported manifest version ${frame[1]}`);
|
|
9656
|
-
}
|
|
9657
|
-
if (frame[2] !== 0 || frame[3] !== 0)
|
|
9658
|
-
throw new Error("manifest reserved bits must be zero");
|
|
9659
|
-
const view2 = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
|
|
9660
|
-
const groupId = view2.getBigUint64(4);
|
|
9661
|
-
if (frameType === SOURCE_AUTH_OBJECT_ENTRY_FRAME) {
|
|
9662
|
-
const entry = {
|
|
9663
|
-
kind: "object",
|
|
9664
|
-
groupId,
|
|
9665
|
-
objectId: view2.getUint32(12),
|
|
9666
|
-
trueLength: view2.getUint32(16),
|
|
9667
|
-
digest: frame.slice(20, 52)
|
|
9668
|
-
};
|
|
9669
|
-
requireTrueLength(entry.trueLength);
|
|
9670
|
-
return entry;
|
|
9671
|
-
}
|
|
9672
|
-
const close = {
|
|
9673
|
-
kind: "close",
|
|
9674
|
-
groupId,
|
|
9675
|
-
objectCount: view2.getUint32(12),
|
|
9676
|
-
root: frame.slice(16, 48),
|
|
9677
|
-
signature: frame.slice(48, 112)
|
|
10018
|
+
return {
|
|
10019
|
+
kid: readU32(view2, 4),
|
|
10020
|
+
epoch: readU32(view2, 8),
|
|
10021
|
+
mseq: readU642(view2, 12),
|
|
10022
|
+
firstSeq: readU642(view2, 20),
|
|
10023
|
+
count,
|
|
10024
|
+
hashAlg: bytes[30],
|
|
10025
|
+
flags: bytes[31],
|
|
10026
|
+
sent: readU32(view2, 32),
|
|
10027
|
+
ctx: bytes.slice(36, 68),
|
|
10028
|
+
digests,
|
|
10029
|
+
signature: bytes.slice(bytes.byteLength - BCPV2_SIGNATURE_LENGTH),
|
|
10030
|
+
body,
|
|
10031
|
+
raw: bytes
|
|
9678
10032
|
};
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
}
|
|
9682
|
-
|
|
10033
|
+
}
|
|
10034
|
+
function bcProvenanceV2SignedMessage(record, endpoint) {
|
|
10035
|
+
const { source, group } = endpointBytes(endpoint);
|
|
10036
|
+
const prefix = new Uint8Array(SIGNING_DOMAIN.byteLength + 4 + source.byteLength + group.byteLength + 2);
|
|
10037
|
+
let offset = 0;
|
|
10038
|
+
prefix.set(SIGNING_DOMAIN, offset);
|
|
10039
|
+
offset += SIGNING_DOMAIN.byteLength;
|
|
10040
|
+
prefix.set(u322(endpoint.streamId), offset);
|
|
10041
|
+
offset += 4;
|
|
10042
|
+
prefix.set(source, offset);
|
|
10043
|
+
offset += source.byteLength;
|
|
10044
|
+
prefix.set(group, offset);
|
|
10045
|
+
offset += group.byteLength;
|
|
10046
|
+
prefix.set(u16(endpoint.manifestPort), offset);
|
|
10047
|
+
const message = new Uint8Array(prefix.byteLength + record.body.byteLength);
|
|
10048
|
+
message.set(prefix);
|
|
10049
|
+
message.set(record.body, prefix.byteLength);
|
|
10050
|
+
return message;
|
|
10051
|
+
}
|
|
10052
|
+
function bcProvenanceV2DatagramDigest(endpoint, payload) {
|
|
10053
|
+
if (payload.byteLength > 65535)
|
|
10054
|
+
throw new Error("datagram payload exceeds u16 length");
|
|
10055
|
+
const { source, group } = endpointBytes(endpoint);
|
|
10056
|
+
const pseudoheader = new Uint8Array(source.byteLength + group.byteLength + 2 + 2 + 2 + 2 + 4);
|
|
10057
|
+
let offset = 0;
|
|
10058
|
+
pseudoheader.set(source, offset);
|
|
10059
|
+
offset += source.byteLength;
|
|
10060
|
+
pseudoheader.set(group, offset);
|
|
10061
|
+
offset += group.byteLength;
|
|
10062
|
+
pseudoheader.set([0, 17], offset);
|
|
10063
|
+
offset += 2;
|
|
10064
|
+
pseudoheader.set(u16(payload.byteLength), offset);
|
|
10065
|
+
offset += 2;
|
|
10066
|
+
pseudoheader.set(u16(endpoint.port), offset);
|
|
10067
|
+
offset += 2;
|
|
10068
|
+
pseudoheader.set(u16(endpoint.port), offset);
|
|
10069
|
+
offset += 2;
|
|
10070
|
+
pseudoheader.set(u322(endpoint.streamId), offset);
|
|
10071
|
+
const input = new Uint8Array(pseudoheader.byteLength + payload.byteLength);
|
|
10072
|
+
input.set(pseudoheader);
|
|
10073
|
+
input.set(payload, pseudoheader.byteLength);
|
|
10074
|
+
return sha2562(input);
|
|
9683
10075
|
}
|
|
9684
10076
|
|
|
9685
|
-
// ../mmt-manifest-verify/
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
if (
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
for (const key of keys) {
|
|
9693
|
-
if (key.firstEpoch <= epoch && (signer === void 0 || key.firstEpoch > signer.firstEpoch))
|
|
9694
|
-
signer = key;
|
|
10077
|
+
// ../mmt-manifest-verify/node_modules/@noble/curves/esm/utils.js
|
|
10078
|
+
var _0n = /* @__PURE__ */ BigInt(0);
|
|
10079
|
+
var _1n = /* @__PURE__ */ BigInt(1);
|
|
10080
|
+
function _abool2(value, title = "") {
|
|
10081
|
+
if (typeof value !== "boolean") {
|
|
10082
|
+
const prefix = title && `"${title}"`;
|
|
10083
|
+
throw new Error(prefix + "expected boolean, got type=" + typeof value);
|
|
9695
10084
|
}
|
|
9696
|
-
|
|
9697
|
-
return void 0;
|
|
9698
|
-
return signer.publicKey;
|
|
9699
|
-
}
|
|
9700
|
-
function manifestBindingId(trackName, sourceSymbolFormat) {
|
|
9701
|
-
return JSON.stringify([trackName, sourceSymbolFormat]);
|
|
9702
|
-
}
|
|
9703
|
-
function createWebCryptoEd25519Verifier(subtle = globalThis.crypto.subtle) {
|
|
9704
|
-
return async (publicKey, message, signature) => {
|
|
9705
|
-
const keyBytes = Uint8Array.from(publicKey);
|
|
9706
|
-
const messageBytes = Uint8Array.from(message);
|
|
9707
|
-
const signatureBytes = Uint8Array.from(signature);
|
|
9708
|
-
const key = await subtle.importKey("raw", keyBytes.buffer, "Ed25519", false, ["verify"]);
|
|
9709
|
-
return subtle.verify("Ed25519", key, signatureBytes.buffer, messageBytes.buffer);
|
|
9710
|
-
};
|
|
10085
|
+
return value;
|
|
9711
10086
|
}
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
10087
|
+
function _abytes2(value, length, title = "") {
|
|
10088
|
+
const bytes = isBytes(value);
|
|
10089
|
+
const len = value?.length;
|
|
10090
|
+
const needsLen = length !== void 0;
|
|
10091
|
+
if (!bytes || needsLen && len !== length) {
|
|
10092
|
+
const prefix = title && `"${title}" `;
|
|
10093
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
10094
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
10095
|
+
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
10096
|
+
}
|
|
10097
|
+
return value;
|
|
10098
|
+
}
|
|
10099
|
+
function hexToNumber(hex2) {
|
|
10100
|
+
if (typeof hex2 !== "string")
|
|
10101
|
+
throw new Error("hex string expected, got " + typeof hex2);
|
|
10102
|
+
return hex2 === "" ? _0n : BigInt("0x" + hex2);
|
|
10103
|
+
}
|
|
10104
|
+
function bytesToNumberBE(bytes) {
|
|
10105
|
+
return hexToNumber(bytesToHex(bytes));
|
|
10106
|
+
}
|
|
10107
|
+
function bytesToNumberLE(bytes) {
|
|
10108
|
+
abytes(bytes);
|
|
10109
|
+
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
|
10110
|
+
}
|
|
10111
|
+
function numberToBytesBE(n, len) {
|
|
10112
|
+
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
|
|
10113
|
+
}
|
|
10114
|
+
function numberToBytesLE(n, len) {
|
|
10115
|
+
return numberToBytesBE(n, len).reverse();
|
|
10116
|
+
}
|
|
10117
|
+
function ensureBytes(title, hex2, expectedLength) {
|
|
10118
|
+
let res;
|
|
10119
|
+
if (typeof hex2 === "string") {
|
|
10120
|
+
try {
|
|
10121
|
+
res = hexToBytes(hex2);
|
|
10122
|
+
} catch (e) {
|
|
10123
|
+
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
10124
|
+
}
|
|
10125
|
+
} else if (isBytes(hex2)) {
|
|
10126
|
+
res = Uint8Array.from(hex2);
|
|
10127
|
+
} else {
|
|
10128
|
+
throw new Error(title + " must be hex string or Uint8Array");
|
|
10129
|
+
}
|
|
10130
|
+
const len = res.length;
|
|
10131
|
+
if (typeof expectedLength === "number" && len !== expectedLength)
|
|
10132
|
+
throw new Error(title + " of length " + expectedLength + " expected, got " + len);
|
|
10133
|
+
return res;
|
|
10134
|
+
}
|
|
10135
|
+
function equalBytes2(a, b) {
|
|
10136
|
+
if (a.length !== b.length)
|
|
9721
10137
|
return false;
|
|
9722
10138
|
let diff = 0;
|
|
9723
|
-
for (let
|
|
9724
|
-
diff |=
|
|
10139
|
+
for (let i = 0; i < a.length; i++)
|
|
10140
|
+
diff |= a[i] ^ b[i];
|
|
9725
10141
|
return diff === 0;
|
|
10142
|
+
}
|
|
10143
|
+
function copyBytes(bytes) {
|
|
10144
|
+
return Uint8Array.from(bytes);
|
|
10145
|
+
}
|
|
10146
|
+
var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
10147
|
+
function inRange(n, min, max) {
|
|
10148
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
10149
|
+
}
|
|
10150
|
+
function aInRange(title, n, min, max) {
|
|
10151
|
+
if (!inRange(n, min, max))
|
|
10152
|
+
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
10153
|
+
}
|
|
10154
|
+
function bitLen(n) {
|
|
10155
|
+
let len;
|
|
10156
|
+
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
10157
|
+
;
|
|
10158
|
+
return len;
|
|
10159
|
+
}
|
|
10160
|
+
var bitMask = (n) => (_1n << BigInt(n)) - _1n;
|
|
10161
|
+
function _validateObject(object, fields, optFields = {}) {
|
|
10162
|
+
if (!object || typeof object !== "object")
|
|
10163
|
+
throw new Error("expected valid options object");
|
|
10164
|
+
function checkField(fieldName, expectedType, isOpt) {
|
|
10165
|
+
const val = object[fieldName];
|
|
10166
|
+
if (isOpt && val === void 0)
|
|
10167
|
+
return;
|
|
10168
|
+
const current = typeof val;
|
|
10169
|
+
if (current !== expectedType || val === null)
|
|
10170
|
+
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
10171
|
+
}
|
|
10172
|
+
Object.entries(fields).forEach(([k, v]) => checkField(k, v, false));
|
|
10173
|
+
Object.entries(optFields).forEach(([k, v]) => checkField(k, v, true));
|
|
10174
|
+
}
|
|
10175
|
+
var notImplemented = () => {
|
|
10176
|
+
throw new Error("not implemented");
|
|
9726
10177
|
};
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
quarantinedBytes: 0
|
|
10178
|
+
function memoized(fn) {
|
|
10179
|
+
const map = /* @__PURE__ */ new WeakMap();
|
|
10180
|
+
return (arg, ...args) => {
|
|
10181
|
+
const val = map.get(arg);
|
|
10182
|
+
if (val !== void 0)
|
|
10183
|
+
return val;
|
|
10184
|
+
const computed = fn(arg, ...args);
|
|
10185
|
+
map.set(arg, computed);
|
|
10186
|
+
return computed;
|
|
9737
10187
|
};
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
9742
|
-
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9854
|
-
if (
|
|
9855
|
-
return
|
|
10188
|
+
}
|
|
10189
|
+
|
|
10190
|
+
// ../mmt-manifest-verify/node_modules/@noble/curves/esm/abstract/modular.js
|
|
10191
|
+
var _0n2 = BigInt(0);
|
|
10192
|
+
var _1n2 = BigInt(1);
|
|
10193
|
+
var _2n = /* @__PURE__ */ BigInt(2);
|
|
10194
|
+
var _3n = /* @__PURE__ */ BigInt(3);
|
|
10195
|
+
var _4n = /* @__PURE__ */ BigInt(4);
|
|
10196
|
+
var _5n = /* @__PURE__ */ BigInt(5);
|
|
10197
|
+
var _7n = /* @__PURE__ */ BigInt(7);
|
|
10198
|
+
var _8n = /* @__PURE__ */ BigInt(8);
|
|
10199
|
+
var _9n = /* @__PURE__ */ BigInt(9);
|
|
10200
|
+
var _16n = /* @__PURE__ */ BigInt(16);
|
|
10201
|
+
function mod(a, b) {
|
|
10202
|
+
const result = a % b;
|
|
10203
|
+
return result >= _0n2 ? result : b + result;
|
|
10204
|
+
}
|
|
10205
|
+
function pow2(x, power, modulo) {
|
|
10206
|
+
let res = x;
|
|
10207
|
+
while (power-- > _0n2) {
|
|
10208
|
+
res *= res;
|
|
10209
|
+
res %= modulo;
|
|
10210
|
+
}
|
|
10211
|
+
return res;
|
|
10212
|
+
}
|
|
10213
|
+
function invert(number, modulo) {
|
|
10214
|
+
if (number === _0n2)
|
|
10215
|
+
throw new Error("invert: expected non-zero number");
|
|
10216
|
+
if (modulo <= _0n2)
|
|
10217
|
+
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
10218
|
+
let a = mod(number, modulo);
|
|
10219
|
+
let b = modulo;
|
|
10220
|
+
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
10221
|
+
while (a !== _0n2) {
|
|
10222
|
+
const q = b / a;
|
|
10223
|
+
const r = b % a;
|
|
10224
|
+
const m = x - u * q;
|
|
10225
|
+
const n = y - v * q;
|
|
10226
|
+
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
10227
|
+
}
|
|
10228
|
+
const gcd = b;
|
|
10229
|
+
if (gcd !== _1n2)
|
|
10230
|
+
throw new Error("invert: does not exist");
|
|
10231
|
+
return mod(x, modulo);
|
|
10232
|
+
}
|
|
10233
|
+
function assertIsSquare(Fp2, root, n) {
|
|
10234
|
+
if (!Fp2.eql(Fp2.sqr(root), n))
|
|
10235
|
+
throw new Error("Cannot find square root");
|
|
10236
|
+
}
|
|
10237
|
+
function sqrt3mod4(Fp2, n) {
|
|
10238
|
+
const p1div4 = (Fp2.ORDER + _1n2) / _4n;
|
|
10239
|
+
const root = Fp2.pow(n, p1div4);
|
|
10240
|
+
assertIsSquare(Fp2, root, n);
|
|
10241
|
+
return root;
|
|
10242
|
+
}
|
|
10243
|
+
function sqrt5mod8(Fp2, n) {
|
|
10244
|
+
const p5div8 = (Fp2.ORDER - _5n) / _8n;
|
|
10245
|
+
const n2 = Fp2.mul(n, _2n);
|
|
10246
|
+
const v = Fp2.pow(n2, p5div8);
|
|
10247
|
+
const nv = Fp2.mul(n, v);
|
|
10248
|
+
const i = Fp2.mul(Fp2.mul(nv, _2n), v);
|
|
10249
|
+
const root = Fp2.mul(nv, Fp2.sub(i, Fp2.ONE));
|
|
10250
|
+
assertIsSquare(Fp2, root, n);
|
|
10251
|
+
return root;
|
|
10252
|
+
}
|
|
10253
|
+
function sqrt9mod16(P) {
|
|
10254
|
+
const Fp_ = Field(P);
|
|
10255
|
+
const tn = tonelliShanks(P);
|
|
10256
|
+
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
10257
|
+
const c2 = tn(Fp_, c1);
|
|
10258
|
+
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
10259
|
+
const c4 = (P + _7n) / _16n;
|
|
10260
|
+
return (Fp2, n) => {
|
|
10261
|
+
let tv1 = Fp2.pow(n, c4);
|
|
10262
|
+
let tv2 = Fp2.mul(tv1, c1);
|
|
10263
|
+
const tv3 = Fp2.mul(tv1, c2);
|
|
10264
|
+
const tv4 = Fp2.mul(tv1, c3);
|
|
10265
|
+
const e1 = Fp2.eql(Fp2.sqr(tv2), n);
|
|
10266
|
+
const e2 = Fp2.eql(Fp2.sqr(tv3), n);
|
|
10267
|
+
tv1 = Fp2.cmov(tv1, tv2, e1);
|
|
10268
|
+
tv2 = Fp2.cmov(tv4, tv3, e2);
|
|
10269
|
+
const e3 = Fp2.eql(Fp2.sqr(tv2), n);
|
|
10270
|
+
const root = Fp2.cmov(tv1, tv2, e3);
|
|
10271
|
+
assertIsSquare(Fp2, root, n);
|
|
10272
|
+
return root;
|
|
10273
|
+
};
|
|
10274
|
+
}
|
|
10275
|
+
function tonelliShanks(P) {
|
|
10276
|
+
if (P < _3n)
|
|
10277
|
+
throw new Error("sqrt is not defined for small field");
|
|
10278
|
+
let Q = P - _1n2;
|
|
10279
|
+
let S = 0;
|
|
10280
|
+
while (Q % _2n === _0n2) {
|
|
10281
|
+
Q /= _2n;
|
|
10282
|
+
S++;
|
|
10283
|
+
}
|
|
10284
|
+
let Z = _2n;
|
|
10285
|
+
const _Fp = Field(P);
|
|
10286
|
+
while (FpLegendre(_Fp, Z) === 1) {
|
|
10287
|
+
if (Z++ > 1e3)
|
|
10288
|
+
throw new Error("Cannot find square root: probably non-prime P");
|
|
10289
|
+
}
|
|
10290
|
+
if (S === 1)
|
|
10291
|
+
return sqrt3mod4;
|
|
10292
|
+
let cc = _Fp.pow(Z, Q);
|
|
10293
|
+
const Q1div2 = (Q + _1n2) / _2n;
|
|
10294
|
+
return function tonelliSlow(Fp2, n) {
|
|
10295
|
+
if (Fp2.is0(n))
|
|
10296
|
+
return n;
|
|
10297
|
+
if (FpLegendre(Fp2, n) !== 1)
|
|
10298
|
+
throw new Error("Cannot find square root");
|
|
10299
|
+
let M = S;
|
|
10300
|
+
let c = Fp2.mul(Fp2.ONE, cc);
|
|
10301
|
+
let t = Fp2.pow(n, Q);
|
|
10302
|
+
let R = Fp2.pow(n, Q1div2);
|
|
10303
|
+
while (!Fp2.eql(t, Fp2.ONE)) {
|
|
10304
|
+
if (Fp2.is0(t))
|
|
10305
|
+
return Fp2.ZERO;
|
|
10306
|
+
let i = 1;
|
|
10307
|
+
let t_tmp = Fp2.sqr(t);
|
|
10308
|
+
while (!Fp2.eql(t_tmp, Fp2.ONE)) {
|
|
10309
|
+
i++;
|
|
10310
|
+
t_tmp = Fp2.sqr(t_tmp);
|
|
10311
|
+
if (i === M)
|
|
10312
|
+
throw new Error("Cannot find square root");
|
|
9856
10313
|
}
|
|
9857
|
-
const
|
|
9858
|
-
|
|
9859
|
-
|
|
10314
|
+
const exponent = _1n2 << BigInt(M - i - 1);
|
|
10315
|
+
const b = Fp2.pow(c, exponent);
|
|
10316
|
+
M = i;
|
|
10317
|
+
c = Fp2.sqr(b);
|
|
10318
|
+
t = Fp2.mul(t, c);
|
|
10319
|
+
R = Fp2.mul(R, b);
|
|
10320
|
+
}
|
|
10321
|
+
return R;
|
|
10322
|
+
};
|
|
10323
|
+
}
|
|
10324
|
+
function FpSqrt(P) {
|
|
10325
|
+
if (P % _4n === _3n)
|
|
10326
|
+
return sqrt3mod4;
|
|
10327
|
+
if (P % _8n === _5n)
|
|
10328
|
+
return sqrt5mod8;
|
|
10329
|
+
if (P % _16n === _9n)
|
|
10330
|
+
return sqrt9mod16(P);
|
|
10331
|
+
return tonelliShanks(P);
|
|
10332
|
+
}
|
|
10333
|
+
var isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n2) === _1n2;
|
|
10334
|
+
var FIELD_FIELDS = [
|
|
10335
|
+
"create",
|
|
10336
|
+
"isValid",
|
|
10337
|
+
"is0",
|
|
10338
|
+
"neg",
|
|
10339
|
+
"inv",
|
|
10340
|
+
"sqrt",
|
|
10341
|
+
"sqr",
|
|
10342
|
+
"eql",
|
|
10343
|
+
"add",
|
|
10344
|
+
"sub",
|
|
10345
|
+
"mul",
|
|
10346
|
+
"pow",
|
|
10347
|
+
"div",
|
|
10348
|
+
"addN",
|
|
10349
|
+
"subN",
|
|
10350
|
+
"mulN",
|
|
10351
|
+
"sqrN"
|
|
10352
|
+
];
|
|
10353
|
+
function validateField(field) {
|
|
10354
|
+
const initial = {
|
|
10355
|
+
ORDER: "bigint",
|
|
10356
|
+
MASK: "bigint",
|
|
10357
|
+
BYTES: "number",
|
|
10358
|
+
BITS: "number"
|
|
10359
|
+
};
|
|
10360
|
+
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
10361
|
+
map[val] = "function";
|
|
10362
|
+
return map;
|
|
10363
|
+
}, initial);
|
|
10364
|
+
_validateObject(field, opts);
|
|
10365
|
+
return field;
|
|
10366
|
+
}
|
|
10367
|
+
function FpPow(Fp2, num, power) {
|
|
10368
|
+
if (power < _0n2)
|
|
10369
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
10370
|
+
if (power === _0n2)
|
|
10371
|
+
return Fp2.ONE;
|
|
10372
|
+
if (power === _1n2)
|
|
10373
|
+
return num;
|
|
10374
|
+
let p = Fp2.ONE;
|
|
10375
|
+
let d = num;
|
|
10376
|
+
while (power > _0n2) {
|
|
10377
|
+
if (power & _1n2)
|
|
10378
|
+
p = Fp2.mul(p, d);
|
|
10379
|
+
d = Fp2.sqr(d);
|
|
10380
|
+
power >>= _1n2;
|
|
10381
|
+
}
|
|
10382
|
+
return p;
|
|
10383
|
+
}
|
|
10384
|
+
function FpInvertBatch(Fp2, nums, passZero = false) {
|
|
10385
|
+
const inverted = new Array(nums.length).fill(passZero ? Fp2.ZERO : void 0);
|
|
10386
|
+
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
10387
|
+
if (Fp2.is0(num))
|
|
10388
|
+
return acc;
|
|
10389
|
+
inverted[i] = acc;
|
|
10390
|
+
return Fp2.mul(acc, num);
|
|
10391
|
+
}, Fp2.ONE);
|
|
10392
|
+
const invertedAcc = Fp2.inv(multipliedAcc);
|
|
10393
|
+
nums.reduceRight((acc, num, i) => {
|
|
10394
|
+
if (Fp2.is0(num))
|
|
10395
|
+
return acc;
|
|
10396
|
+
inverted[i] = Fp2.mul(acc, inverted[i]);
|
|
10397
|
+
return Fp2.mul(acc, num);
|
|
10398
|
+
}, invertedAcc);
|
|
10399
|
+
return inverted;
|
|
10400
|
+
}
|
|
10401
|
+
function FpLegendre(Fp2, n) {
|
|
10402
|
+
const p1mod2 = (Fp2.ORDER - _1n2) / _2n;
|
|
10403
|
+
const powered = Fp2.pow(n, p1mod2);
|
|
10404
|
+
const yes = Fp2.eql(powered, Fp2.ONE);
|
|
10405
|
+
const zero = Fp2.eql(powered, Fp2.ZERO);
|
|
10406
|
+
const no = Fp2.eql(powered, Fp2.neg(Fp2.ONE));
|
|
10407
|
+
if (!yes && !zero && !no)
|
|
10408
|
+
throw new Error("invalid Legendre symbol result");
|
|
10409
|
+
return yes ? 1 : zero ? 0 : -1;
|
|
10410
|
+
}
|
|
10411
|
+
function nLength(n, nBitLength) {
|
|
10412
|
+
if (nBitLength !== void 0)
|
|
10413
|
+
anumber(nBitLength);
|
|
10414
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length;
|
|
10415
|
+
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
10416
|
+
return { nBitLength: _nBitLength, nByteLength };
|
|
10417
|
+
}
|
|
10418
|
+
function Field(ORDER, bitLenOrOpts, isLE = false, opts = {}) {
|
|
10419
|
+
if (ORDER <= _0n2)
|
|
10420
|
+
throw new Error("invalid field: expected ORDER > 0, got " + ORDER);
|
|
10421
|
+
let _nbitLength = void 0;
|
|
10422
|
+
let _sqrt = void 0;
|
|
10423
|
+
let modFromBytes = false;
|
|
10424
|
+
let allowedLengths = void 0;
|
|
10425
|
+
if (typeof bitLenOrOpts === "object" && bitLenOrOpts != null) {
|
|
10426
|
+
if (opts.sqrt || isLE)
|
|
10427
|
+
throw new Error("cannot specify opts in two arguments");
|
|
10428
|
+
const _opts = bitLenOrOpts;
|
|
10429
|
+
if (_opts.BITS)
|
|
10430
|
+
_nbitLength = _opts.BITS;
|
|
10431
|
+
if (_opts.sqrt)
|
|
10432
|
+
_sqrt = _opts.sqrt;
|
|
10433
|
+
if (typeof _opts.isLE === "boolean")
|
|
10434
|
+
isLE = _opts.isLE;
|
|
10435
|
+
if (typeof _opts.modFromBytes === "boolean")
|
|
10436
|
+
modFromBytes = _opts.modFromBytes;
|
|
10437
|
+
allowedLengths = _opts.allowedLengths;
|
|
10438
|
+
} else {
|
|
10439
|
+
if (typeof bitLenOrOpts === "number")
|
|
10440
|
+
_nbitLength = bitLenOrOpts;
|
|
10441
|
+
if (opts.sqrt)
|
|
10442
|
+
_sqrt = opts.sqrt;
|
|
10443
|
+
}
|
|
10444
|
+
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, _nbitLength);
|
|
10445
|
+
if (BYTES > 2048)
|
|
10446
|
+
throw new Error("invalid field: expected ORDER of <= 2048 bytes");
|
|
10447
|
+
let sqrtP;
|
|
10448
|
+
const f = Object.freeze({
|
|
10449
|
+
ORDER,
|
|
10450
|
+
isLE,
|
|
10451
|
+
BITS,
|
|
10452
|
+
BYTES,
|
|
10453
|
+
MASK: bitMask(BITS),
|
|
10454
|
+
ZERO: _0n2,
|
|
10455
|
+
ONE: _1n2,
|
|
10456
|
+
allowedLengths,
|
|
10457
|
+
create: (num) => mod(num, ORDER),
|
|
10458
|
+
isValid: (num) => {
|
|
10459
|
+
if (typeof num !== "bigint")
|
|
10460
|
+
throw new Error("invalid field element: expected bigint, got " + typeof num);
|
|
10461
|
+
return _0n2 <= num && num < ORDER;
|
|
10462
|
+
},
|
|
10463
|
+
is0: (num) => num === _0n2,
|
|
10464
|
+
// is valid and invertible
|
|
10465
|
+
isValidNot0: (num) => !f.is0(num) && f.isValid(num),
|
|
10466
|
+
isOdd: (num) => (num & _1n2) === _1n2,
|
|
10467
|
+
neg: (num) => mod(-num, ORDER),
|
|
10468
|
+
eql: (lhs, rhs) => lhs === rhs,
|
|
10469
|
+
sqr: (num) => mod(num * num, ORDER),
|
|
10470
|
+
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
|
10471
|
+
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
|
10472
|
+
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
|
10473
|
+
pow: (num, power) => FpPow(f, num, power),
|
|
10474
|
+
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
|
10475
|
+
// Same as above, but doesn't normalize
|
|
10476
|
+
sqrN: (num) => num * num,
|
|
10477
|
+
addN: (lhs, rhs) => lhs + rhs,
|
|
10478
|
+
subN: (lhs, rhs) => lhs - rhs,
|
|
10479
|
+
mulN: (lhs, rhs) => lhs * rhs,
|
|
10480
|
+
inv: (num) => invert(num, ORDER),
|
|
10481
|
+
sqrt: _sqrt || ((n) => {
|
|
10482
|
+
if (!sqrtP)
|
|
10483
|
+
sqrtP = FpSqrt(ORDER);
|
|
10484
|
+
return sqrtP(f, n);
|
|
10485
|
+
}),
|
|
10486
|
+
toBytes: (num) => isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES),
|
|
10487
|
+
fromBytes: (bytes, skipValidation = true) => {
|
|
10488
|
+
if (allowedLengths) {
|
|
10489
|
+
if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
10490
|
+
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
10491
|
+
}
|
|
10492
|
+
const padded = new Uint8Array(BYTES);
|
|
10493
|
+
padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
|
|
10494
|
+
bytes = padded;
|
|
9860
10495
|
}
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
if (
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
10496
|
+
if (bytes.length !== BYTES)
|
|
10497
|
+
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
10498
|
+
let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
10499
|
+
if (modFromBytes)
|
|
10500
|
+
scalar = mod(scalar, ORDER);
|
|
10501
|
+
if (!skipValidation) {
|
|
10502
|
+
if (!f.isValid(scalar))
|
|
10503
|
+
throw new Error("invalid field element: outside of range 0..ORDER");
|
|
9868
10504
|
}
|
|
9869
|
-
|
|
9870
|
-
|
|
10505
|
+
return scalar;
|
|
10506
|
+
},
|
|
10507
|
+
// TODO: we don't need it here, move out to separate fn
|
|
10508
|
+
invertBatch: (lst) => FpInvertBatch(f, lst),
|
|
10509
|
+
// We can't move this out because Fp6, Fp12 implement it
|
|
10510
|
+
// and it's unclear what to return in there.
|
|
10511
|
+
cmov: (a, b, c) => c ? b : a
|
|
10512
|
+
});
|
|
10513
|
+
return Object.freeze(f);
|
|
10514
|
+
}
|
|
10515
|
+
|
|
10516
|
+
// ../mmt-manifest-verify/node_modules/@noble/curves/esm/abstract/curve.js
|
|
10517
|
+
var _0n3 = BigInt(0);
|
|
10518
|
+
var _1n3 = BigInt(1);
|
|
10519
|
+
function negateCt(condition, item) {
|
|
10520
|
+
const neg = item.negate();
|
|
10521
|
+
return condition ? neg : item;
|
|
10522
|
+
}
|
|
10523
|
+
function normalizeZ(c, points) {
|
|
10524
|
+
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
10525
|
+
return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
|
|
10526
|
+
}
|
|
10527
|
+
function validateW(W, bits) {
|
|
10528
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
|
10529
|
+
throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W);
|
|
10530
|
+
}
|
|
10531
|
+
function calcWOpts(W, scalarBits) {
|
|
10532
|
+
validateW(W, scalarBits);
|
|
10533
|
+
const windows = Math.ceil(scalarBits / W) + 1;
|
|
10534
|
+
const windowSize = 2 ** (W - 1);
|
|
10535
|
+
const maxNumber = 2 ** W;
|
|
10536
|
+
const mask = bitMask(W);
|
|
10537
|
+
const shiftBy = BigInt(W);
|
|
10538
|
+
return { windows, windowSize, mask, maxNumber, shiftBy };
|
|
10539
|
+
}
|
|
10540
|
+
function calcOffsets(n, window, wOpts) {
|
|
10541
|
+
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
|
10542
|
+
let wbits = Number(n & mask);
|
|
10543
|
+
let nextN = n >> shiftBy;
|
|
10544
|
+
if (wbits > windowSize) {
|
|
10545
|
+
wbits -= maxNumber;
|
|
10546
|
+
nextN += _1n3;
|
|
10547
|
+
}
|
|
10548
|
+
const offsetStart = window * windowSize;
|
|
10549
|
+
const offset = offsetStart + Math.abs(wbits) - 1;
|
|
10550
|
+
const isZero = wbits === 0;
|
|
10551
|
+
const isNeg = wbits < 0;
|
|
10552
|
+
const isNegF = window % 2 !== 0;
|
|
10553
|
+
const offsetF = offsetStart;
|
|
10554
|
+
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
|
10555
|
+
}
|
|
10556
|
+
function validateMSMPoints(points, c) {
|
|
10557
|
+
if (!Array.isArray(points))
|
|
10558
|
+
throw new Error("array expected");
|
|
10559
|
+
points.forEach((p, i) => {
|
|
10560
|
+
if (!(p instanceof c))
|
|
10561
|
+
throw new Error("invalid point at index " + i);
|
|
10562
|
+
});
|
|
10563
|
+
}
|
|
10564
|
+
function validateMSMScalars(scalars, field) {
|
|
10565
|
+
if (!Array.isArray(scalars))
|
|
10566
|
+
throw new Error("array of scalars expected");
|
|
10567
|
+
scalars.forEach((s, i) => {
|
|
10568
|
+
if (!field.isValid(s))
|
|
10569
|
+
throw new Error("invalid scalar at index " + i);
|
|
10570
|
+
});
|
|
10571
|
+
}
|
|
10572
|
+
var pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
10573
|
+
var pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
10574
|
+
function getW(P) {
|
|
10575
|
+
return pointWindowSizes.get(P) || 1;
|
|
10576
|
+
}
|
|
10577
|
+
function assert0(n) {
|
|
10578
|
+
if (n !== _0n3)
|
|
10579
|
+
throw new Error("invalid wNAF");
|
|
10580
|
+
}
|
|
10581
|
+
var wNAF = class {
|
|
10582
|
+
// Parametrized with a given Point class (not individual point)
|
|
10583
|
+
constructor(Point, bits) {
|
|
10584
|
+
this.BASE = Point.BASE;
|
|
10585
|
+
this.ZERO = Point.ZERO;
|
|
10586
|
+
this.Fn = Point.Fn;
|
|
10587
|
+
this.bits = bits;
|
|
10588
|
+
}
|
|
10589
|
+
// non-const time multiplication ladder
|
|
10590
|
+
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
10591
|
+
let d = elm;
|
|
10592
|
+
while (n > _0n3) {
|
|
10593
|
+
if (n & _1n3)
|
|
10594
|
+
p = p.add(d);
|
|
10595
|
+
d = d.double();
|
|
10596
|
+
n >>= _1n3;
|
|
10597
|
+
}
|
|
10598
|
+
return p;
|
|
10599
|
+
}
|
|
10600
|
+
/**
|
|
10601
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
10602
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
10603
|
+
* Number of precomputed points depends on the curve size:
|
|
10604
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
10605
|
+
* - 𝑊 is the window size
|
|
10606
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
10607
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
10608
|
+
* @param point Point instance
|
|
10609
|
+
* @param W window size
|
|
10610
|
+
* @returns precomputed point tables flattened to a single array
|
|
10611
|
+
*/
|
|
10612
|
+
precomputeWindow(point, W) {
|
|
10613
|
+
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
10614
|
+
const points = [];
|
|
10615
|
+
let p = point;
|
|
10616
|
+
let base = p;
|
|
10617
|
+
for (let window = 0; window < windows; window++) {
|
|
10618
|
+
base = p;
|
|
10619
|
+
points.push(base);
|
|
10620
|
+
for (let i = 1; i < windowSize; i++) {
|
|
10621
|
+
base = base.add(p);
|
|
10622
|
+
points.push(base);
|
|
9871
10623
|
}
|
|
9872
|
-
|
|
9873
|
-
} catch {
|
|
9874
|
-
release();
|
|
9875
|
-
this.#failure(identity, "verifierError");
|
|
9876
|
-
return { action: "play", verified: false, reason: "verifierError" };
|
|
10624
|
+
p = base.double();
|
|
9877
10625
|
}
|
|
10626
|
+
return points;
|
|
9878
10627
|
}
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9889
|
-
|
|
9890
|
-
|
|
9891
|
-
|
|
9892
|
-
|
|
9893
|
-
|
|
9894
|
-
|
|
9895
|
-
|
|
9896
|
-
|
|
9897
|
-
|
|
9898
|
-
const oldest = track.groups.entries().next().value;
|
|
9899
|
-
if (!oldest)
|
|
9900
|
-
break;
|
|
9901
|
-
const [oldestId, oldestGroup] = oldest;
|
|
9902
|
-
for (const pending of [...oldestGroup.pending.values()]) {
|
|
9903
|
-
this.#removePending(track, oldestGroup, pending);
|
|
9904
|
-
this.#giveUpOnPending(pending);
|
|
9905
|
-
this.#failure(pending.identity, "manifestAbsent");
|
|
9906
|
-
}
|
|
9907
|
-
track.manifestEntries -= oldestGroup.entries.size;
|
|
9908
|
-
track.groups.delete(oldestId);
|
|
10628
|
+
/**
|
|
10629
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
10630
|
+
* More compact implementation:
|
|
10631
|
+
* https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
|
10632
|
+
* @returns real and fake (for const-time) points
|
|
10633
|
+
*/
|
|
10634
|
+
wNAF(W, precomputes, n) {
|
|
10635
|
+
if (!this.Fn.isValid(n))
|
|
10636
|
+
throw new Error("invalid scalar");
|
|
10637
|
+
let p = this.ZERO;
|
|
10638
|
+
let f = this.BASE;
|
|
10639
|
+
const wo = calcWOpts(W, this.bits);
|
|
10640
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
10641
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
|
10642
|
+
n = nextN;
|
|
10643
|
+
if (isZero) {
|
|
10644
|
+
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
10645
|
+
} else {
|
|
10646
|
+
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
9909
10647
|
}
|
|
9910
10648
|
}
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
#validateIdentity(track, identity) {
|
|
9914
|
-
const coordinates = track.context.mapper.derive(Number(identity.groupId), identity.objectId);
|
|
9915
|
-
return identity.ssId === void 0 || coordinates.ssId === identity.ssId;
|
|
10649
|
+
assert0(n);
|
|
10650
|
+
return { p, f };
|
|
9916
10651
|
}
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
|
|
9925
|
-
if (
|
|
9926
|
-
|
|
9927
|
-
|
|
10652
|
+
/**
|
|
10653
|
+
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
|
10654
|
+
* @param acc accumulator point to add result of multiplication
|
|
10655
|
+
* @returns point
|
|
10656
|
+
*/
|
|
10657
|
+
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
10658
|
+
const wo = calcWOpts(W, this.bits);
|
|
10659
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
10660
|
+
if (n === _0n3)
|
|
10661
|
+
break;
|
|
10662
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
10663
|
+
n = nextN;
|
|
10664
|
+
if (isZero) {
|
|
10665
|
+
continue;
|
|
10666
|
+
} else {
|
|
10667
|
+
const item = precomputes[offset];
|
|
10668
|
+
acc = acc.add(isNeg ? item.negate() : item);
|
|
9928
10669
|
}
|
|
9929
|
-
|
|
9930
|
-
|
|
10670
|
+
}
|
|
10671
|
+
assert0(n);
|
|
10672
|
+
return acc;
|
|
10673
|
+
}
|
|
10674
|
+
getPrecomputes(W, point, transform) {
|
|
10675
|
+
let comp = pointPrecomputes.get(point);
|
|
10676
|
+
if (!comp) {
|
|
10677
|
+
comp = this.precomputeWindow(point, W);
|
|
10678
|
+
if (W !== 1) {
|
|
10679
|
+
if (typeof transform === "function")
|
|
10680
|
+
comp = transform(comp);
|
|
10681
|
+
pointPrecomputes.set(point, comp);
|
|
9931
10682
|
}
|
|
9932
|
-
return { action: "stall", verified: false };
|
|
9933
10683
|
}
|
|
9934
|
-
|
|
9935
|
-
this.#stats.verified++;
|
|
9936
|
-
return { action: "play", verified: true };
|
|
10684
|
+
return comp;
|
|
9937
10685
|
}
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
console.warn(JSON.stringify({ event: "manifest-enforce-drop", track: identity.trackName, group: String(identity.groupId), object: identity.objectId, reason }));
|
|
9942
|
-
return { action: "drop", verified: false, reason };
|
|
9943
|
-
}
|
|
9944
|
-
release();
|
|
9945
|
-
return { action: "play", verified: false, reason };
|
|
10686
|
+
cached(point, scalar, transform) {
|
|
10687
|
+
const W = getW(point);
|
|
10688
|
+
return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
|
|
9946
10689
|
}
|
|
9947
|
-
|
|
9948
|
-
|
|
9949
|
-
|
|
10690
|
+
unsafe(point, scalar, transform, prev) {
|
|
10691
|
+
const W = getW(point);
|
|
10692
|
+
if (W === 1)
|
|
10693
|
+
return this._unsafeLadder(point, scalar, prev);
|
|
10694
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
|
|
9950
10695
|
}
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
10696
|
+
// We calculate precomputes for elliptic curve point multiplication
|
|
10697
|
+
// using windowed method. This specifies window size and
|
|
10698
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
|
10699
|
+
createCache(P, W) {
|
|
10700
|
+
validateW(W, this.bits);
|
|
10701
|
+
pointWindowSizes.set(P, W);
|
|
10702
|
+
pointPrecomputes.delete(P);
|
|
10703
|
+
}
|
|
10704
|
+
hasCache(elm) {
|
|
10705
|
+
return getW(elm) !== 1;
|
|
10706
|
+
}
|
|
10707
|
+
};
|
|
10708
|
+
function pippenger(c, fieldN, points, scalars) {
|
|
10709
|
+
validateMSMPoints(points, c);
|
|
10710
|
+
validateMSMScalars(scalars, fieldN);
|
|
10711
|
+
const plength = points.length;
|
|
10712
|
+
const slength = scalars.length;
|
|
10713
|
+
if (plength !== slength)
|
|
10714
|
+
throw new Error("arrays of points and scalars must have equal length");
|
|
10715
|
+
const zero = c.ZERO;
|
|
10716
|
+
const wbits = bitLen(BigInt(plength));
|
|
10717
|
+
let windowSize = 1;
|
|
10718
|
+
if (wbits > 12)
|
|
10719
|
+
windowSize = wbits - 3;
|
|
10720
|
+
else if (wbits > 4)
|
|
10721
|
+
windowSize = wbits - 2;
|
|
10722
|
+
else if (wbits > 0)
|
|
10723
|
+
windowSize = 2;
|
|
10724
|
+
const MASK = bitMask(windowSize);
|
|
10725
|
+
const buckets = new Array(Number(MASK) + 1).fill(zero);
|
|
10726
|
+
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
|
10727
|
+
let sum = zero;
|
|
10728
|
+
for (let i = lastBits; i >= 0; i -= windowSize) {
|
|
10729
|
+
buckets.fill(zero);
|
|
10730
|
+
for (let j = 0; j < slength; j++) {
|
|
10731
|
+
const scalar = scalars[j];
|
|
10732
|
+
const wbits2 = Number(scalar >> BigInt(i) & MASK);
|
|
10733
|
+
buckets[wbits2] = buckets[wbits2].add(points[j]);
|
|
10734
|
+
}
|
|
10735
|
+
let resI = zero;
|
|
10736
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
|
10737
|
+
sumI = sumI.add(buckets[j]);
|
|
10738
|
+
resI = resI.add(sumI);
|
|
10739
|
+
}
|
|
10740
|
+
sum = sum.add(resI);
|
|
10741
|
+
if (i !== 0)
|
|
10742
|
+
for (let j = 0; j < windowSize; j++)
|
|
10743
|
+
sum = sum.double();
|
|
10744
|
+
}
|
|
10745
|
+
return sum;
|
|
10746
|
+
}
|
|
10747
|
+
function createField(order, field, isLE) {
|
|
10748
|
+
if (field) {
|
|
10749
|
+
if (field.ORDER !== order)
|
|
10750
|
+
throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
|
|
10751
|
+
validateField(field);
|
|
10752
|
+
return field;
|
|
10753
|
+
} else {
|
|
10754
|
+
return Field(order, { isLE });
|
|
10755
|
+
}
|
|
10756
|
+
}
|
|
10757
|
+
function _createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
10758
|
+
if (FpFnLE === void 0)
|
|
10759
|
+
FpFnLE = type === "edwards";
|
|
10760
|
+
if (!CURVE || typeof CURVE !== "object")
|
|
10761
|
+
throw new Error(`expected valid ${type} CURVE object`);
|
|
10762
|
+
for (const p of ["p", "n", "h"]) {
|
|
10763
|
+
const val = CURVE[p];
|
|
10764
|
+
if (!(typeof val === "bigint" && val > _0n3))
|
|
10765
|
+
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
10766
|
+
}
|
|
10767
|
+
const Fp2 = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
10768
|
+
const Fn2 = createField(CURVE.n, curveOpts.Fn, FpFnLE);
|
|
10769
|
+
const _b = type === "weierstrass" ? "b" : "d";
|
|
10770
|
+
const params = ["Gx", "Gy", "a", _b];
|
|
10771
|
+
for (const p of params) {
|
|
10772
|
+
if (!Fp2.isValid(CURVE[p]))
|
|
10773
|
+
throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
|
|
10774
|
+
}
|
|
10775
|
+
CURVE = Object.freeze(Object.assign({}, CURVE));
|
|
10776
|
+
return { CURVE, Fp: Fp2, Fn: Fn2 };
|
|
10777
|
+
}
|
|
10778
|
+
|
|
10779
|
+
// ../mmt-manifest-verify/node_modules/@noble/curves/esm/abstract/edwards.js
|
|
10780
|
+
var _0n4 = BigInt(0);
|
|
10781
|
+
var _1n4 = BigInt(1);
|
|
10782
|
+
var _2n2 = BigInt(2);
|
|
10783
|
+
var _8n2 = BigInt(8);
|
|
10784
|
+
function isEdValidXY(Fp2, CURVE, x, y) {
|
|
10785
|
+
const x2 = Fp2.sqr(x);
|
|
10786
|
+
const y2 = Fp2.sqr(y);
|
|
10787
|
+
const left = Fp2.add(Fp2.mul(CURVE.a, x2), y2);
|
|
10788
|
+
const right = Fp2.add(Fp2.ONE, Fp2.mul(CURVE.d, Fp2.mul(x2, y2)));
|
|
10789
|
+
return Fp2.eql(left, right);
|
|
10790
|
+
}
|
|
10791
|
+
function edwards(params, extraOpts = {}) {
|
|
10792
|
+
const validated = _createCurveFields("edwards", params, extraOpts, extraOpts.FpFnLE);
|
|
10793
|
+
const { Fp: Fp2, Fn: Fn2 } = validated;
|
|
10794
|
+
let CURVE = validated.CURVE;
|
|
10795
|
+
const { h: cofactor } = CURVE;
|
|
10796
|
+
_validateObject(extraOpts, {}, { uvRatio: "function" });
|
|
10797
|
+
const MASK = _2n2 << BigInt(Fn2.BYTES * 8) - _1n4;
|
|
10798
|
+
const modP = (n) => Fp2.create(n);
|
|
10799
|
+
const uvRatio2 = extraOpts.uvRatio || ((u, v) => {
|
|
10800
|
+
try {
|
|
10801
|
+
return { isValid: true, value: Fp2.sqrt(Fp2.div(u, v)) };
|
|
10802
|
+
} catch (e) {
|
|
10803
|
+
return { isValid: false, value: _0n4 };
|
|
9978
10804
|
}
|
|
9979
|
-
|
|
9980
|
-
|
|
10805
|
+
});
|
|
10806
|
+
if (!isEdValidXY(Fp2, CURVE, CURVE.Gx, CURVE.Gy))
|
|
10807
|
+
throw new Error("bad curve params: generator point");
|
|
10808
|
+
function acoord(title, n, banZero = false) {
|
|
10809
|
+
const min = banZero ? _1n4 : _0n4;
|
|
10810
|
+
aInRange("coordinate " + title, n, min, MASK);
|
|
10811
|
+
return n;
|
|
10812
|
+
}
|
|
10813
|
+
function aextpoint(other) {
|
|
10814
|
+
if (!(other instanceof Point))
|
|
10815
|
+
throw new Error("ExtendedPoint expected");
|
|
10816
|
+
}
|
|
10817
|
+
const toAffineMemo = memoized((p, iz) => {
|
|
10818
|
+
const { X, Y, Z } = p;
|
|
10819
|
+
const is0 = p.is0();
|
|
10820
|
+
if (iz == null)
|
|
10821
|
+
iz = is0 ? _8n2 : Fp2.inv(Z);
|
|
10822
|
+
const x = modP(X * iz);
|
|
10823
|
+
const y = modP(Y * iz);
|
|
10824
|
+
const zz = Fp2.mul(Z, iz);
|
|
10825
|
+
if (is0)
|
|
10826
|
+
return { x: _0n4, y: _1n4 };
|
|
10827
|
+
if (zz !== _1n4)
|
|
10828
|
+
throw new Error("invZ was invalid");
|
|
10829
|
+
return { x, y };
|
|
10830
|
+
});
|
|
10831
|
+
const assertValidMemo = memoized((p) => {
|
|
10832
|
+
const { a, d } = CURVE;
|
|
10833
|
+
if (p.is0())
|
|
10834
|
+
throw new Error("bad point: ZERO");
|
|
10835
|
+
const { X, Y, Z, T } = p;
|
|
10836
|
+
const X2 = modP(X * X);
|
|
10837
|
+
const Y2 = modP(Y * Y);
|
|
10838
|
+
const Z2 = modP(Z * Z);
|
|
10839
|
+
const Z4 = modP(Z2 * Z2);
|
|
10840
|
+
const aX2 = modP(X2 * a);
|
|
10841
|
+
const left = modP(Z2 * modP(aX2 + Y2));
|
|
10842
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2)));
|
|
10843
|
+
if (left !== right)
|
|
10844
|
+
throw new Error("bad point: equation left != right (1)");
|
|
10845
|
+
const XY = modP(X * Y);
|
|
10846
|
+
const ZT = modP(Z * T);
|
|
10847
|
+
if (XY !== ZT)
|
|
10848
|
+
throw new Error("bad point: equation left != right (2)");
|
|
10849
|
+
return true;
|
|
10850
|
+
});
|
|
10851
|
+
class Point {
|
|
10852
|
+
constructor(X, Y, Z, T) {
|
|
10853
|
+
this.X = acoord("x", X);
|
|
10854
|
+
this.Y = acoord("y", Y);
|
|
10855
|
+
this.Z = acoord("z", Z, true);
|
|
10856
|
+
this.T = acoord("t", T);
|
|
10857
|
+
Object.freeze(this);
|
|
10858
|
+
}
|
|
10859
|
+
static CURVE() {
|
|
10860
|
+
return CURVE;
|
|
10861
|
+
}
|
|
10862
|
+
static fromAffine(p) {
|
|
10863
|
+
if (p instanceof Point)
|
|
10864
|
+
throw new Error("extended point not allowed");
|
|
10865
|
+
const { x, y } = p || {};
|
|
10866
|
+
acoord("x", x);
|
|
10867
|
+
acoord("y", y);
|
|
10868
|
+
return new Point(x, y, _1n4, modP(x * y));
|
|
10869
|
+
}
|
|
10870
|
+
// Uses algo from RFC8032 5.1.3.
|
|
10871
|
+
static fromBytes(bytes, zip215 = false) {
|
|
10872
|
+
const len = Fp2.BYTES;
|
|
10873
|
+
const { a, d } = CURVE;
|
|
10874
|
+
bytes = copyBytes(_abytes2(bytes, len, "point"));
|
|
10875
|
+
_abool2(zip215, "zip215");
|
|
10876
|
+
const normed = copyBytes(bytes);
|
|
10877
|
+
const lastByte = bytes[len - 1];
|
|
10878
|
+
normed[len - 1] = lastByte & ~128;
|
|
10879
|
+
const y = bytesToNumberLE(normed);
|
|
10880
|
+
const max = zip215 ? MASK : Fp2.ORDER;
|
|
10881
|
+
aInRange("point.y", y, _0n4, max);
|
|
10882
|
+
const y2 = modP(y * y);
|
|
10883
|
+
const u = modP(y2 - _1n4);
|
|
10884
|
+
const v = modP(d * y2 - a);
|
|
10885
|
+
let { isValid, value: x } = uvRatio2(u, v);
|
|
10886
|
+
if (!isValid)
|
|
10887
|
+
throw new Error("bad point: invalid y coordinate");
|
|
10888
|
+
const isXOdd = (x & _1n4) === _1n4;
|
|
10889
|
+
const isLastByteOdd = (lastByte & 128) !== 0;
|
|
10890
|
+
if (!zip215 && x === _0n4 && isLastByteOdd)
|
|
10891
|
+
throw new Error("bad point: x=0 and x_0=1");
|
|
10892
|
+
if (isLastByteOdd !== isXOdd)
|
|
10893
|
+
x = modP(-x);
|
|
10894
|
+
return Point.fromAffine({ x, y });
|
|
10895
|
+
}
|
|
10896
|
+
static fromHex(bytes, zip215 = false) {
|
|
10897
|
+
return Point.fromBytes(ensureBytes("point", bytes), zip215);
|
|
10898
|
+
}
|
|
10899
|
+
get x() {
|
|
10900
|
+
return this.toAffine().x;
|
|
10901
|
+
}
|
|
10902
|
+
get y() {
|
|
10903
|
+
return this.toAffine().y;
|
|
10904
|
+
}
|
|
10905
|
+
precompute(windowSize = 8, isLazy = true) {
|
|
10906
|
+
wnaf.createCache(this, windowSize);
|
|
10907
|
+
if (!isLazy)
|
|
10908
|
+
this.multiply(_2n2);
|
|
10909
|
+
return this;
|
|
10910
|
+
}
|
|
10911
|
+
// Useful in fromAffine() - not for fromBytes(), which always created valid points.
|
|
10912
|
+
assertValidity() {
|
|
10913
|
+
assertValidMemo(this);
|
|
10914
|
+
}
|
|
10915
|
+
// Compare one point to another.
|
|
10916
|
+
equals(other) {
|
|
10917
|
+
aextpoint(other);
|
|
10918
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
10919
|
+
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
10920
|
+
const X1Z2 = modP(X1 * Z2);
|
|
10921
|
+
const X2Z1 = modP(X2 * Z1);
|
|
10922
|
+
const Y1Z2 = modP(Y1 * Z2);
|
|
10923
|
+
const Y2Z1 = modP(Y2 * Z1);
|
|
10924
|
+
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
10925
|
+
}
|
|
10926
|
+
is0() {
|
|
10927
|
+
return this.equals(Point.ZERO);
|
|
10928
|
+
}
|
|
10929
|
+
negate() {
|
|
10930
|
+
return new Point(modP(-this.X), this.Y, this.Z, modP(-this.T));
|
|
10931
|
+
}
|
|
10932
|
+
// Fast algo for doubling Extended Point.
|
|
10933
|
+
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
|
|
10934
|
+
// Cost: 4M + 4S + 1*a + 6add + 1*2.
|
|
10935
|
+
double() {
|
|
10936
|
+
const { a } = CURVE;
|
|
10937
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
10938
|
+
const A = modP(X1 * X1);
|
|
10939
|
+
const B = modP(Y1 * Y1);
|
|
10940
|
+
const C = modP(_2n2 * modP(Z1 * Z1));
|
|
10941
|
+
const D = modP(a * A);
|
|
10942
|
+
const x1y1 = X1 + Y1;
|
|
10943
|
+
const E = modP(modP(x1y1 * x1y1) - A - B);
|
|
10944
|
+
const G = D + B;
|
|
10945
|
+
const F = G - C;
|
|
10946
|
+
const H = D - B;
|
|
10947
|
+
const X3 = modP(E * F);
|
|
10948
|
+
const Y3 = modP(G * H);
|
|
10949
|
+
const T3 = modP(E * H);
|
|
10950
|
+
const Z3 = modP(F * G);
|
|
10951
|
+
return new Point(X3, Y3, Z3, T3);
|
|
10952
|
+
}
|
|
10953
|
+
// Fast algo for adding 2 Extended Points.
|
|
10954
|
+
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
|
10955
|
+
// Cost: 9M + 1*a + 1*d + 7add.
|
|
10956
|
+
add(other) {
|
|
10957
|
+
aextpoint(other);
|
|
10958
|
+
const { a, d } = CURVE;
|
|
10959
|
+
const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
|
|
10960
|
+
const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
|
|
10961
|
+
const A = modP(X1 * X2);
|
|
10962
|
+
const B = modP(Y1 * Y2);
|
|
10963
|
+
const C = modP(T1 * d * T2);
|
|
10964
|
+
const D = modP(Z1 * Z2);
|
|
10965
|
+
const E = modP((X1 + Y1) * (X2 + Y2) - A - B);
|
|
10966
|
+
const F = D - C;
|
|
10967
|
+
const G = D + C;
|
|
10968
|
+
const H = modP(B - a * A);
|
|
10969
|
+
const X3 = modP(E * F);
|
|
10970
|
+
const Y3 = modP(G * H);
|
|
10971
|
+
const T3 = modP(E * H);
|
|
10972
|
+
const Z3 = modP(F * G);
|
|
10973
|
+
return new Point(X3, Y3, Z3, T3);
|
|
10974
|
+
}
|
|
10975
|
+
subtract(other) {
|
|
10976
|
+
return this.add(other.negate());
|
|
10977
|
+
}
|
|
10978
|
+
// Constant-time multiplication.
|
|
10979
|
+
multiply(scalar) {
|
|
10980
|
+
if (!Fn2.isValidNot0(scalar))
|
|
10981
|
+
throw new Error("invalid scalar: expected 1 <= sc < curve.n");
|
|
10982
|
+
const { p, f } = wnaf.cached(this, scalar, (p2) => normalizeZ(Point, p2));
|
|
10983
|
+
return normalizeZ(Point, [p, f])[0];
|
|
10984
|
+
}
|
|
10985
|
+
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
10986
|
+
// It's faster, but should only be used when you don't care about
|
|
10987
|
+
// an exposed private key e.g. sig verification.
|
|
10988
|
+
// Does NOT allow scalars higher than CURVE.n.
|
|
10989
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
|
10990
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
|
10991
|
+
if (!Fn2.isValid(scalar))
|
|
10992
|
+
throw new Error("invalid scalar: expected 0 <= sc < curve.n");
|
|
10993
|
+
if (scalar === _0n4)
|
|
10994
|
+
return Point.ZERO;
|
|
10995
|
+
if (this.is0() || scalar === _1n4)
|
|
10996
|
+
return this;
|
|
10997
|
+
return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p), acc);
|
|
10998
|
+
}
|
|
10999
|
+
// Checks if point is of small order.
|
|
11000
|
+
// If you add something to small order point, you will have "dirty"
|
|
11001
|
+
// point with torsion component.
|
|
11002
|
+
// Multiplies point by cofactor and checks if the result is 0.
|
|
11003
|
+
isSmallOrder() {
|
|
11004
|
+
return this.multiplyUnsafe(cofactor).is0();
|
|
11005
|
+
}
|
|
11006
|
+
// Multiplies point by curve order and checks if the result is 0.
|
|
11007
|
+
// Returns `false` is the point is dirty.
|
|
11008
|
+
isTorsionFree() {
|
|
11009
|
+
return wnaf.unsafe(this, CURVE.n).is0();
|
|
11010
|
+
}
|
|
11011
|
+
// Converts Extended point to default (x, y) coordinates.
|
|
11012
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
11013
|
+
toAffine(invertedZ) {
|
|
11014
|
+
return toAffineMemo(this, invertedZ);
|
|
11015
|
+
}
|
|
11016
|
+
clearCofactor() {
|
|
11017
|
+
if (cofactor === _1n4)
|
|
11018
|
+
return this;
|
|
11019
|
+
return this.multiplyUnsafe(cofactor);
|
|
11020
|
+
}
|
|
11021
|
+
toBytes() {
|
|
11022
|
+
const { x, y } = this.toAffine();
|
|
11023
|
+
const bytes = Fp2.toBytes(y);
|
|
11024
|
+
bytes[bytes.length - 1] |= x & _1n4 ? 128 : 0;
|
|
11025
|
+
return bytes;
|
|
11026
|
+
}
|
|
11027
|
+
toHex() {
|
|
11028
|
+
return bytesToHex(this.toBytes());
|
|
11029
|
+
}
|
|
11030
|
+
toString() {
|
|
11031
|
+
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
11032
|
+
}
|
|
11033
|
+
// TODO: remove
|
|
11034
|
+
get ex() {
|
|
11035
|
+
return this.X;
|
|
11036
|
+
}
|
|
11037
|
+
get ey() {
|
|
11038
|
+
return this.Y;
|
|
11039
|
+
}
|
|
11040
|
+
get ez() {
|
|
11041
|
+
return this.Z;
|
|
11042
|
+
}
|
|
11043
|
+
get et() {
|
|
11044
|
+
return this.T;
|
|
11045
|
+
}
|
|
11046
|
+
static normalizeZ(points) {
|
|
11047
|
+
return normalizeZ(Point, points);
|
|
11048
|
+
}
|
|
11049
|
+
static msm(points, scalars) {
|
|
11050
|
+
return pippenger(Point, Fn2, points, scalars);
|
|
11051
|
+
}
|
|
11052
|
+
_setWindowSize(windowSize) {
|
|
11053
|
+
this.precompute(windowSize);
|
|
11054
|
+
}
|
|
11055
|
+
toRawBytes() {
|
|
11056
|
+
return this.toBytes();
|
|
11057
|
+
}
|
|
11058
|
+
}
|
|
11059
|
+
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, _1n4, modP(CURVE.Gx * CURVE.Gy));
|
|
11060
|
+
Point.ZERO = new Point(_0n4, _1n4, _1n4, _0n4);
|
|
11061
|
+
Point.Fp = Fp2;
|
|
11062
|
+
Point.Fn = Fn2;
|
|
11063
|
+
const wnaf = new wNAF(Point, Fn2.BITS);
|
|
11064
|
+
Point.BASE.precompute(8);
|
|
11065
|
+
return Point;
|
|
11066
|
+
}
|
|
11067
|
+
var PrimeEdwardsPoint = class {
|
|
11068
|
+
constructor(ep) {
|
|
11069
|
+
this.ep = ep;
|
|
11070
|
+
}
|
|
11071
|
+
// Static methods that must be implemented by subclasses
|
|
11072
|
+
static fromBytes(_bytes) {
|
|
11073
|
+
notImplemented();
|
|
11074
|
+
}
|
|
11075
|
+
static fromHex(_hex) {
|
|
11076
|
+
notImplemented();
|
|
11077
|
+
}
|
|
11078
|
+
get x() {
|
|
11079
|
+
return this.toAffine().x;
|
|
11080
|
+
}
|
|
11081
|
+
get y() {
|
|
11082
|
+
return this.toAffine().y;
|
|
11083
|
+
}
|
|
11084
|
+
// Common implementations
|
|
11085
|
+
clearCofactor() {
|
|
11086
|
+
return this;
|
|
11087
|
+
}
|
|
11088
|
+
assertValidity() {
|
|
11089
|
+
this.ep.assertValidity();
|
|
11090
|
+
}
|
|
11091
|
+
toAffine(invertedZ) {
|
|
11092
|
+
return this.ep.toAffine(invertedZ);
|
|
11093
|
+
}
|
|
11094
|
+
toHex() {
|
|
11095
|
+
return bytesToHex(this.toBytes());
|
|
11096
|
+
}
|
|
11097
|
+
toString() {
|
|
11098
|
+
return this.toHex();
|
|
11099
|
+
}
|
|
11100
|
+
isTorsionFree() {
|
|
11101
|
+
return true;
|
|
11102
|
+
}
|
|
11103
|
+
isSmallOrder() {
|
|
11104
|
+
return false;
|
|
11105
|
+
}
|
|
11106
|
+
add(other) {
|
|
11107
|
+
this.assertSame(other);
|
|
11108
|
+
return this.init(this.ep.add(other.ep));
|
|
11109
|
+
}
|
|
11110
|
+
subtract(other) {
|
|
11111
|
+
this.assertSame(other);
|
|
11112
|
+
return this.init(this.ep.subtract(other.ep));
|
|
11113
|
+
}
|
|
11114
|
+
multiply(scalar) {
|
|
11115
|
+
return this.init(this.ep.multiply(scalar));
|
|
11116
|
+
}
|
|
11117
|
+
multiplyUnsafe(scalar) {
|
|
11118
|
+
return this.init(this.ep.multiplyUnsafe(scalar));
|
|
11119
|
+
}
|
|
11120
|
+
double() {
|
|
11121
|
+
return this.init(this.ep.double());
|
|
11122
|
+
}
|
|
11123
|
+
negate() {
|
|
11124
|
+
return this.init(this.ep.negate());
|
|
11125
|
+
}
|
|
11126
|
+
precompute(windowSize, isLazy) {
|
|
11127
|
+
return this.init(this.ep.precompute(windowSize, isLazy));
|
|
11128
|
+
}
|
|
11129
|
+
/** @deprecated use `toBytes` */
|
|
11130
|
+
toRawBytes() {
|
|
11131
|
+
return this.toBytes();
|
|
11132
|
+
}
|
|
11133
|
+
};
|
|
11134
|
+
function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
11135
|
+
if (typeof cHash !== "function")
|
|
11136
|
+
throw new Error('"hash" function param is required');
|
|
11137
|
+
_validateObject(eddsaOpts, {}, {
|
|
11138
|
+
adjustScalarBytes: "function",
|
|
11139
|
+
randomBytes: "function",
|
|
11140
|
+
domain: "function",
|
|
11141
|
+
prehash: "function",
|
|
11142
|
+
mapToCurve: "function"
|
|
11143
|
+
});
|
|
11144
|
+
const { prehash } = eddsaOpts;
|
|
11145
|
+
const { BASE, Fp: Fp2, Fn: Fn2 } = Point;
|
|
11146
|
+
const randomBytes2 = eddsaOpts.randomBytes || randomBytes;
|
|
11147
|
+
const adjustScalarBytes2 = eddsaOpts.adjustScalarBytes || ((bytes) => bytes);
|
|
11148
|
+
const domain = eddsaOpts.domain || ((data, ctx, phflag) => {
|
|
11149
|
+
_abool2(phflag, "phflag");
|
|
11150
|
+
if (ctx.length || phflag)
|
|
11151
|
+
throw new Error("Contexts/pre-hash are not supported");
|
|
11152
|
+
return data;
|
|
11153
|
+
});
|
|
11154
|
+
function modN_LE(hash) {
|
|
11155
|
+
return Fn2.create(bytesToNumberLE(hash));
|
|
11156
|
+
}
|
|
11157
|
+
function getPrivateScalar(key) {
|
|
11158
|
+
const len = lengths.secretKey;
|
|
11159
|
+
key = ensureBytes("private key", key, len);
|
|
11160
|
+
const hashed = ensureBytes("hashed private key", cHash(key), 2 * len);
|
|
11161
|
+
const head = adjustScalarBytes2(hashed.slice(0, len));
|
|
11162
|
+
const prefix = hashed.slice(len, 2 * len);
|
|
11163
|
+
const scalar = modN_LE(head);
|
|
11164
|
+
return { head, prefix, scalar };
|
|
11165
|
+
}
|
|
11166
|
+
function getExtendedPublicKey(secretKey) {
|
|
11167
|
+
const { head, prefix, scalar } = getPrivateScalar(secretKey);
|
|
11168
|
+
const point = BASE.multiply(scalar);
|
|
11169
|
+
const pointBytes = point.toBytes();
|
|
11170
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
11171
|
+
}
|
|
11172
|
+
function getPublicKey(secretKey) {
|
|
11173
|
+
return getExtendedPublicKey(secretKey).pointBytes;
|
|
11174
|
+
}
|
|
11175
|
+
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
|
11176
|
+
const msg = concatBytes(...msgs);
|
|
11177
|
+
return modN_LE(cHash(domain(msg, ensureBytes("context", context), !!prehash)));
|
|
11178
|
+
}
|
|
11179
|
+
function sign(msg, secretKey, options = {}) {
|
|
11180
|
+
msg = ensureBytes("message", msg);
|
|
11181
|
+
if (prehash)
|
|
11182
|
+
msg = prehash(msg);
|
|
11183
|
+
const { prefix, scalar, pointBytes } = getExtendedPublicKey(secretKey);
|
|
11184
|
+
const r = hashDomainToScalar(options.context, prefix, msg);
|
|
11185
|
+
const R = BASE.multiply(r).toBytes();
|
|
11186
|
+
const k = hashDomainToScalar(options.context, R, pointBytes, msg);
|
|
11187
|
+
const s = Fn2.create(r + k * scalar);
|
|
11188
|
+
if (!Fn2.isValid(s))
|
|
11189
|
+
throw new Error("sign failed: invalid s");
|
|
11190
|
+
const rs = concatBytes(R, Fn2.toBytes(s));
|
|
11191
|
+
return _abytes2(rs, lengths.signature, "result");
|
|
11192
|
+
}
|
|
11193
|
+
const verifyOpts = { zip215: true };
|
|
11194
|
+
function verify(sig, msg, publicKey, options = verifyOpts) {
|
|
11195
|
+
const { context, zip215 } = options;
|
|
11196
|
+
const len = lengths.signature;
|
|
11197
|
+
sig = ensureBytes("signature", sig, len);
|
|
11198
|
+
msg = ensureBytes("message", msg);
|
|
11199
|
+
publicKey = ensureBytes("publicKey", publicKey, lengths.publicKey);
|
|
11200
|
+
if (zip215 !== void 0)
|
|
11201
|
+
_abool2(zip215, "zip215");
|
|
11202
|
+
if (prehash)
|
|
11203
|
+
msg = prehash(msg);
|
|
11204
|
+
const mid = len / 2;
|
|
11205
|
+
const r = sig.subarray(0, mid);
|
|
11206
|
+
const s = bytesToNumberLE(sig.subarray(mid, len));
|
|
11207
|
+
let A, R, SB;
|
|
9981
11208
|
try {
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
11209
|
+
A = Point.fromBytes(publicKey, zip215);
|
|
11210
|
+
R = Point.fromBytes(r, zip215);
|
|
11211
|
+
SB = BASE.multiplyUnsafe(s);
|
|
11212
|
+
} catch (error) {
|
|
11213
|
+
return false;
|
|
9986
11214
|
}
|
|
9987
|
-
if (
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
11215
|
+
if (!zip215 && A.isSmallOrder())
|
|
11216
|
+
return false;
|
|
11217
|
+
const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);
|
|
11218
|
+
const RkA = R.add(A.multiplyUnsafe(k));
|
|
11219
|
+
return RkA.subtract(SB).clearCofactor().is0();
|
|
11220
|
+
}
|
|
11221
|
+
const _size = Fp2.BYTES;
|
|
11222
|
+
const lengths = {
|
|
11223
|
+
secretKey: _size,
|
|
11224
|
+
publicKey: _size,
|
|
11225
|
+
signature: 2 * _size,
|
|
11226
|
+
seed: _size
|
|
11227
|
+
};
|
|
11228
|
+
function randomSecretKey(seed = randomBytes2(lengths.seed)) {
|
|
11229
|
+
return _abytes2(seed, lengths.seed, "seed");
|
|
11230
|
+
}
|
|
11231
|
+
function keygen(seed) {
|
|
11232
|
+
const secretKey = utils.randomSecretKey(seed);
|
|
11233
|
+
return { secretKey, publicKey: getPublicKey(secretKey) };
|
|
11234
|
+
}
|
|
11235
|
+
function isValidSecretKey(key) {
|
|
11236
|
+
return isBytes(key) && key.length === Fn2.BYTES;
|
|
11237
|
+
}
|
|
11238
|
+
function isValidPublicKey(key, zip215) {
|
|
11239
|
+
try {
|
|
11240
|
+
return !!Point.fromBytes(key, zip215);
|
|
11241
|
+
} catch (error) {
|
|
11242
|
+
return false;
|
|
10001
11243
|
}
|
|
10002
|
-
this.#finishGroupSignature(track, groupId, group, close, signatureValid);
|
|
10003
11244
|
}
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
11245
|
+
const utils = {
|
|
11246
|
+
getExtendedPublicKey,
|
|
11247
|
+
randomSecretKey,
|
|
11248
|
+
isValidSecretKey,
|
|
11249
|
+
isValidPublicKey,
|
|
11250
|
+
/**
|
|
11251
|
+
* Converts ed public key to x public key. Uses formula:
|
|
11252
|
+
* - ed25519:
|
|
11253
|
+
* - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
|
11254
|
+
* - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
|
11255
|
+
* - ed448:
|
|
11256
|
+
* - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
|
11257
|
+
* - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
|
11258
|
+
*/
|
|
11259
|
+
toMontgomery(publicKey) {
|
|
11260
|
+
const { y } = Point.fromBytes(publicKey);
|
|
11261
|
+
const size = lengths.publicKey;
|
|
11262
|
+
const is25519 = size === 32;
|
|
11263
|
+
if (!is25519 && size !== 57)
|
|
11264
|
+
throw new Error("only defined for 25519 and 448");
|
|
11265
|
+
const u = is25519 ? Fp2.div(_1n4 + y, _1n4 - y) : Fp2.div(y - _1n4, y + _1n4);
|
|
11266
|
+
return Fp2.toBytes(u);
|
|
11267
|
+
},
|
|
11268
|
+
toMontgomerySecret(secretKey) {
|
|
11269
|
+
const size = lengths.secretKey;
|
|
11270
|
+
_abytes2(secretKey, size);
|
|
11271
|
+
const hashed = cHash(secretKey.subarray(0, size));
|
|
11272
|
+
return adjustScalarBytes2(hashed).subarray(0, size);
|
|
11273
|
+
},
|
|
11274
|
+
/** @deprecated */
|
|
11275
|
+
randomPrivateKey: randomSecretKey,
|
|
11276
|
+
/** @deprecated */
|
|
11277
|
+
precompute(windowSize = 8, point = Point.BASE) {
|
|
11278
|
+
return point.precompute(windowSize, false);
|
|
10009
11279
|
}
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
11280
|
+
};
|
|
11281
|
+
return Object.freeze({
|
|
11282
|
+
keygen,
|
|
11283
|
+
getPublicKey,
|
|
11284
|
+
sign,
|
|
11285
|
+
verify,
|
|
11286
|
+
utils,
|
|
11287
|
+
Point,
|
|
11288
|
+
lengths
|
|
11289
|
+
});
|
|
11290
|
+
}
|
|
11291
|
+
function _eddsa_legacy_opts_to_new(c) {
|
|
11292
|
+
const CURVE = {
|
|
11293
|
+
a: c.a,
|
|
11294
|
+
d: c.d,
|
|
11295
|
+
p: c.Fp.ORDER,
|
|
11296
|
+
n: c.n,
|
|
11297
|
+
h: c.h,
|
|
11298
|
+
Gx: c.Gx,
|
|
11299
|
+
Gy: c.Gy
|
|
11300
|
+
};
|
|
11301
|
+
const Fp2 = c.Fp;
|
|
11302
|
+
const Fn2 = Field(CURVE.n, c.nBitLength, true);
|
|
11303
|
+
const curveOpts = { Fp: Fp2, Fn: Fn2, uvRatio: c.uvRatio };
|
|
11304
|
+
const eddsaOpts = {
|
|
11305
|
+
randomBytes: c.randomBytes,
|
|
11306
|
+
adjustScalarBytes: c.adjustScalarBytes,
|
|
11307
|
+
domain: c.domain,
|
|
11308
|
+
prehash: c.prehash,
|
|
11309
|
+
mapToCurve: c.mapToCurve
|
|
11310
|
+
};
|
|
11311
|
+
return { CURVE, curveOpts, hash: c.hash, eddsaOpts };
|
|
11312
|
+
}
|
|
11313
|
+
function _eddsa_new_output_to_legacy(c, eddsa2) {
|
|
11314
|
+
const Point = eddsa2.Point;
|
|
11315
|
+
const legacy = Object.assign({}, eddsa2, {
|
|
11316
|
+
ExtendedPoint: Point,
|
|
11317
|
+
CURVE: c,
|
|
11318
|
+
nBitLength: Point.Fn.BITS,
|
|
11319
|
+
nByteLength: Point.Fn.BYTES
|
|
11320
|
+
});
|
|
11321
|
+
return legacy;
|
|
11322
|
+
}
|
|
11323
|
+
function twistedEdwards(c) {
|
|
11324
|
+
const { CURVE, curveOpts, hash, eddsaOpts } = _eddsa_legacy_opts_to_new(c);
|
|
11325
|
+
const Point = edwards(CURVE, curveOpts);
|
|
11326
|
+
const EDDSA = eddsa(Point, hash, eddsaOpts);
|
|
11327
|
+
return _eddsa_new_output_to_legacy(c, EDDSA);
|
|
11328
|
+
}
|
|
11329
|
+
|
|
11330
|
+
// ../mmt-manifest-verify/node_modules/@noble/curves/esm/ed25519.js
|
|
11331
|
+
var _0n5 = /* @__PURE__ */ BigInt(0);
|
|
11332
|
+
var _1n5 = BigInt(1);
|
|
11333
|
+
var _2n3 = BigInt(2);
|
|
11334
|
+
var _3n2 = BigInt(3);
|
|
11335
|
+
var _5n2 = BigInt(5);
|
|
11336
|
+
var _8n3 = BigInt(8);
|
|
11337
|
+
var ed25519_CURVE_p = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
11338
|
+
var ed25519_CURVE = /* @__PURE__ */ (() => ({
|
|
11339
|
+
p: ed25519_CURVE_p,
|
|
11340
|
+
n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
|
|
11341
|
+
h: _8n3,
|
|
11342
|
+
a: BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
|
|
11343
|
+
d: BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),
|
|
11344
|
+
Gx: BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),
|
|
11345
|
+
Gy: BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")
|
|
11346
|
+
}))();
|
|
11347
|
+
function ed25519_pow_2_252_3(x) {
|
|
11348
|
+
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
|
11349
|
+
const P = ed25519_CURVE_p;
|
|
11350
|
+
const x2 = x * x % P;
|
|
11351
|
+
const b2 = x2 * x % P;
|
|
11352
|
+
const b4 = pow2(b2, _2n3, P) * b2 % P;
|
|
11353
|
+
const b5 = pow2(b4, _1n5, P) * x % P;
|
|
11354
|
+
const b10 = pow2(b5, _5n2, P) * b5 % P;
|
|
11355
|
+
const b20 = pow2(b10, _10n, P) * b10 % P;
|
|
11356
|
+
const b40 = pow2(b20, _20n, P) * b20 % P;
|
|
11357
|
+
const b80 = pow2(b40, _40n, P) * b40 % P;
|
|
11358
|
+
const b160 = pow2(b80, _80n, P) * b80 % P;
|
|
11359
|
+
const b240 = pow2(b160, _80n, P) * b80 % P;
|
|
11360
|
+
const b250 = pow2(b240, _10n, P) * b10 % P;
|
|
11361
|
+
const pow_p_5_8 = pow2(b250, _2n3, P) * x % P;
|
|
11362
|
+
return { pow_p_5_8, b2 };
|
|
11363
|
+
}
|
|
11364
|
+
function adjustScalarBytes(bytes) {
|
|
11365
|
+
bytes[0] &= 248;
|
|
11366
|
+
bytes[31] &= 127;
|
|
11367
|
+
bytes[31] |= 64;
|
|
11368
|
+
return bytes;
|
|
11369
|
+
}
|
|
11370
|
+
var ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
11371
|
+
function uvRatio(u, v) {
|
|
11372
|
+
const P = ed25519_CURVE_p;
|
|
11373
|
+
const v3 = mod(v * v * v, P);
|
|
11374
|
+
const v7 = mod(v3 * v3 * v, P);
|
|
11375
|
+
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
11376
|
+
let x = mod(u * v3 * pow, P);
|
|
11377
|
+
const vx2 = mod(v * x * x, P);
|
|
11378
|
+
const root1 = x;
|
|
11379
|
+
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
11380
|
+
const useRoot1 = vx2 === u;
|
|
11381
|
+
const useRoot2 = vx2 === mod(-u, P);
|
|
11382
|
+
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P);
|
|
11383
|
+
if (useRoot1)
|
|
11384
|
+
x = root1;
|
|
11385
|
+
if (useRoot2 || noRoot)
|
|
11386
|
+
x = root2;
|
|
11387
|
+
if (isNegativeLE(x, P))
|
|
11388
|
+
x = mod(-x, P);
|
|
11389
|
+
return { isValid: useRoot1 || useRoot2, value: x };
|
|
11390
|
+
}
|
|
11391
|
+
var Fp = /* @__PURE__ */ (() => Field(ed25519_CURVE.p, { isLE: true }))();
|
|
11392
|
+
var Fn = /* @__PURE__ */ (() => Field(ed25519_CURVE.n, { isLE: true }))();
|
|
11393
|
+
var ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
11394
|
+
...ed25519_CURVE,
|
|
11395
|
+
Fp,
|
|
11396
|
+
hash: sha512,
|
|
11397
|
+
adjustScalarBytes,
|
|
11398
|
+
// dom2
|
|
11399
|
+
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
|
11400
|
+
// Constant-time, u/√v
|
|
11401
|
+
uvRatio
|
|
11402
|
+
}))();
|
|
11403
|
+
var ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
|
11404
|
+
var SQRT_M1 = ED25519_SQRT_M1;
|
|
11405
|
+
var SQRT_AD_MINUS_ONE = /* @__PURE__ */ BigInt("25063068953384623474111414158702152701244531502492656460079210482610430750235");
|
|
11406
|
+
var INVSQRT_A_MINUS_D = /* @__PURE__ */ BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578");
|
|
11407
|
+
var ONE_MINUS_D_SQ = /* @__PURE__ */ BigInt("1159843021668779879193775521855586647937357759715417654439879720876111806838");
|
|
11408
|
+
var D_MINUS_ONE_SQ = /* @__PURE__ */ BigInt("40440834346308536858101042469323190826248399146238708352240133220865137265952");
|
|
11409
|
+
var invertSqrt = (number) => uvRatio(_1n5, number);
|
|
11410
|
+
var MAX_255B = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
11411
|
+
var bytes255ToNumberLE = (bytes) => ed25519.Point.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
|
11412
|
+
function calcElligatorRistrettoMap(r0) {
|
|
11413
|
+
const { d } = ed25519_CURVE;
|
|
11414
|
+
const P = ed25519_CURVE_p;
|
|
11415
|
+
const mod2 = (n) => Fp.create(n);
|
|
11416
|
+
const r = mod2(SQRT_M1 * r0 * r0);
|
|
11417
|
+
const Ns = mod2((r + _1n5) * ONE_MINUS_D_SQ);
|
|
11418
|
+
let c = BigInt(-1);
|
|
11419
|
+
const D = mod2((c - d * r) * mod2(r + d));
|
|
11420
|
+
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
11421
|
+
let s_ = mod2(s * r0);
|
|
11422
|
+
if (!isNegativeLE(s_, P))
|
|
11423
|
+
s_ = mod2(-s_);
|
|
11424
|
+
if (!Ns_D_is_sq)
|
|
11425
|
+
s = s_;
|
|
11426
|
+
if (!Ns_D_is_sq)
|
|
11427
|
+
c = r;
|
|
11428
|
+
const Nt = mod2(c * (r - _1n5) * D_MINUS_ONE_SQ - D);
|
|
11429
|
+
const s2 = s * s;
|
|
11430
|
+
const W0 = mod2((s + s) * D);
|
|
11431
|
+
const W1 = mod2(Nt * SQRT_AD_MINUS_ONE);
|
|
11432
|
+
const W2 = mod2(_1n5 - s2);
|
|
11433
|
+
const W3 = mod2(_1n5 + s2);
|
|
11434
|
+
return new ed25519.Point(mod2(W0 * W3), mod2(W2 * W1), mod2(W1 * W3), mod2(W0 * W2));
|
|
11435
|
+
}
|
|
11436
|
+
function ristretto255_map(bytes) {
|
|
11437
|
+
abytes(bytes, 64);
|
|
11438
|
+
const r1 = bytes255ToNumberLE(bytes.subarray(0, 32));
|
|
11439
|
+
const R1 = calcElligatorRistrettoMap(r1);
|
|
11440
|
+
const r2 = bytes255ToNumberLE(bytes.subarray(32, 64));
|
|
11441
|
+
const R2 = calcElligatorRistrettoMap(r2);
|
|
11442
|
+
return new _RistrettoPoint(R1.add(R2));
|
|
11443
|
+
}
|
|
11444
|
+
var _RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
11445
|
+
constructor(ep) {
|
|
11446
|
+
super(ep);
|
|
11447
|
+
}
|
|
11448
|
+
static fromAffine(ap) {
|
|
11449
|
+
return new __RistrettoPoint(ed25519.Point.fromAffine(ap));
|
|
11450
|
+
}
|
|
11451
|
+
assertSame(other) {
|
|
11452
|
+
if (!(other instanceof __RistrettoPoint))
|
|
11453
|
+
throw new Error("RistrettoPoint expected");
|
|
11454
|
+
}
|
|
11455
|
+
init(ep) {
|
|
11456
|
+
return new __RistrettoPoint(ep);
|
|
11457
|
+
}
|
|
11458
|
+
/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
|
|
11459
|
+
static hashToCurve(hex2) {
|
|
11460
|
+
return ristretto255_map(ensureBytes("ristrettoHash", hex2, 64));
|
|
11461
|
+
}
|
|
11462
|
+
static fromBytes(bytes) {
|
|
11463
|
+
abytes(bytes, 32);
|
|
11464
|
+
const { a, d } = ed25519_CURVE;
|
|
11465
|
+
const P = ed25519_CURVE_p;
|
|
11466
|
+
const mod2 = (n) => Fp.create(n);
|
|
11467
|
+
const s = bytes255ToNumberLE(bytes);
|
|
11468
|
+
if (!equalBytes2(Fp.toBytes(s), bytes) || isNegativeLE(s, P))
|
|
11469
|
+
throw new Error("invalid ristretto255 encoding 1");
|
|
11470
|
+
const s2 = mod2(s * s);
|
|
11471
|
+
const u1 = mod2(_1n5 + a * s2);
|
|
11472
|
+
const u2 = mod2(_1n5 - a * s2);
|
|
11473
|
+
const u1_2 = mod2(u1 * u1);
|
|
11474
|
+
const u2_2 = mod2(u2 * u2);
|
|
11475
|
+
const v = mod2(a * d * u1_2 - u2_2);
|
|
11476
|
+
const { isValid, value: I } = invertSqrt(mod2(v * u2_2));
|
|
11477
|
+
const Dx = mod2(I * u2);
|
|
11478
|
+
const Dy = mod2(I * Dx * v);
|
|
11479
|
+
let x = mod2((s + s) * Dx);
|
|
11480
|
+
if (isNegativeLE(x, P))
|
|
11481
|
+
x = mod2(-x);
|
|
11482
|
+
const y = mod2(u1 * Dy);
|
|
11483
|
+
const t = mod2(x * y);
|
|
11484
|
+
if (!isValid || isNegativeLE(t, P) || y === _0n5)
|
|
11485
|
+
throw new Error("invalid ristretto255 encoding 2");
|
|
11486
|
+
return new __RistrettoPoint(new ed25519.Point(x, y, _1n5, t));
|
|
11487
|
+
}
|
|
11488
|
+
/**
|
|
11489
|
+
* Converts ristretto-encoded string to ristretto point.
|
|
11490
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
|
|
11491
|
+
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
11492
|
+
*/
|
|
11493
|
+
static fromHex(hex2) {
|
|
11494
|
+
return __RistrettoPoint.fromBytes(ensureBytes("ristrettoHex", hex2, 32));
|
|
11495
|
+
}
|
|
11496
|
+
static msm(points, scalars) {
|
|
11497
|
+
return pippenger(__RistrettoPoint, ed25519.Point.Fn, points, scalars);
|
|
11498
|
+
}
|
|
11499
|
+
/**
|
|
11500
|
+
* Encodes ristretto point to Uint8Array.
|
|
11501
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).
|
|
11502
|
+
*/
|
|
11503
|
+
toBytes() {
|
|
11504
|
+
let { X, Y, Z, T } = this.ep;
|
|
11505
|
+
const P = ed25519_CURVE_p;
|
|
11506
|
+
const mod2 = (n) => Fp.create(n);
|
|
11507
|
+
const u1 = mod2(mod2(Z + Y) * mod2(Z - Y));
|
|
11508
|
+
const u2 = mod2(X * Y);
|
|
11509
|
+
const u2sq = mod2(u2 * u2);
|
|
11510
|
+
const { value: invsqrt } = invertSqrt(mod2(u1 * u2sq));
|
|
11511
|
+
const D1 = mod2(invsqrt * u1);
|
|
11512
|
+
const D2 = mod2(invsqrt * u2);
|
|
11513
|
+
const zInv = mod2(D1 * D2 * T);
|
|
11514
|
+
let D;
|
|
11515
|
+
if (isNegativeLE(T * zInv, P)) {
|
|
11516
|
+
let _x = mod2(Y * SQRT_M1);
|
|
11517
|
+
let _y = mod2(X * SQRT_M1);
|
|
11518
|
+
X = _x;
|
|
11519
|
+
Y = _y;
|
|
11520
|
+
D = mod2(D1 * INVSQRT_A_MINUS_D);
|
|
11521
|
+
} else {
|
|
11522
|
+
D = D2;
|
|
10023
11523
|
}
|
|
11524
|
+
if (isNegativeLE(X * zInv, P))
|
|
11525
|
+
Y = mod2(-Y);
|
|
11526
|
+
let s = mod2((Z - Y) * D);
|
|
11527
|
+
if (isNegativeLE(s, P))
|
|
11528
|
+
s = mod2(-s);
|
|
11529
|
+
return Fp.toBytes(s);
|
|
10024
11530
|
}
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
10029
|
-
|
|
11531
|
+
/**
|
|
11532
|
+
* Compares two Ristretto points.
|
|
11533
|
+
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals).
|
|
11534
|
+
*/
|
|
11535
|
+
equals(other) {
|
|
11536
|
+
this.assertSame(other);
|
|
11537
|
+
const { X: X1, Y: Y1 } = this.ep;
|
|
11538
|
+
const { X: X2, Y: Y2 } = other.ep;
|
|
11539
|
+
const mod2 = (n) => Fp.create(n);
|
|
11540
|
+
const one = mod2(X1 * Y2) === mod2(Y1 * X2);
|
|
11541
|
+
const two = mod2(Y1 * Y2) === mod2(X1 * X2);
|
|
11542
|
+
return one || two;
|
|
11543
|
+
}
|
|
11544
|
+
is0() {
|
|
11545
|
+
return this.equals(__RistrettoPoint.ZERO);
|
|
11546
|
+
}
|
|
11547
|
+
};
|
|
11548
|
+
_RistrettoPoint.BASE = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.BASE))();
|
|
11549
|
+
_RistrettoPoint.ZERO = /* @__PURE__ */ (() => new _RistrettoPoint(ed25519.Point.ZERO))();
|
|
11550
|
+
_RistrettoPoint.Fp = /* @__PURE__ */ (() => Fp)();
|
|
11551
|
+
_RistrettoPoint.Fn = /* @__PURE__ */ (() => Fn)();
|
|
11552
|
+
|
|
11553
|
+
// ../mmt-manifest-verify/dist/bc-provenance-v2-receiver.js
|
|
11554
|
+
var BCPV2_LEAD_BOUND_MS = 5e3;
|
|
11555
|
+
var REPLAY_WINDOW = 64n;
|
|
11556
|
+
var BUCKET_DEPTH = 64;
|
|
11557
|
+
var BUCKET_RATE_PER_MS = 1;
|
|
11558
|
+
var hex = (bytes) => Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
11559
|
+
function sameBytes(a, b) {
|
|
11560
|
+
if (a.byteLength !== b.byteLength)
|
|
11561
|
+
return false;
|
|
11562
|
+
let diff = 0;
|
|
11563
|
+
for (let i = 0; i < a.byteLength; i++)
|
|
11564
|
+
diff |= a[i] ^ b[i];
|
|
11565
|
+
return diff === 0;
|
|
11566
|
+
}
|
|
11567
|
+
var BcProvenanceV2Receiver = class {
|
|
11568
|
+
maxAuthDelayMs;
|
|
11569
|
+
manifestTimerMs;
|
|
11570
|
+
widenMs;
|
|
11571
|
+
/** Datagrams that left a hold queue at expiry, per path: the loss signal for failover. */
|
|
11572
|
+
expired = { multicast: 0, unicast: 0 };
|
|
11573
|
+
/**
|
|
11574
|
+
* Unicast repair (Section 7.2.7 step 2): on a receiver that can request it, how
|
|
11575
|
+
* long ago (ms) the first packet admitted into the oldest open block with an FEC
|
|
11576
|
+
* deadline was admitted; undefined with none open. A pending entry still live
|
|
11577
|
+
* then is kept instead of expiring, and is released with the block, under the
|
|
11578
|
+
* open-block bound of [MOQ-FEC] Section 9.
|
|
11579
|
+
*/
|
|
11580
|
+
keepPendingAgeMs = null;
|
|
11581
|
+
cfg;
|
|
11582
|
+
now;
|
|
11583
|
+
verifySig;
|
|
11584
|
+
accepted;
|
|
11585
|
+
queueLimit;
|
|
11586
|
+
current = null;
|
|
11587
|
+
previous = null;
|
|
11588
|
+
graceStart = {};
|
|
11589
|
+
hashAlg = null;
|
|
11590
|
+
verified = /* @__PURE__ */ new Map();
|
|
11591
|
+
highest = { multicast: /* @__PURE__ */ new Map(), mirror: /* @__PURE__ */ new Map() };
|
|
11592
|
+
closedAt = /* @__PURE__ */ new Map();
|
|
11593
|
+
lead = null;
|
|
11594
|
+
pending = /* @__PURE__ */ new Map();
|
|
11595
|
+
admittedUntil = /* @__PURE__ */ new Map();
|
|
11596
|
+
hold = { multicast: [], unicast: [] };
|
|
11597
|
+
holdBytes = { multicast: 0, unicast: 0 };
|
|
11598
|
+
order = 0;
|
|
11599
|
+
buckets;
|
|
11600
|
+
constructor(cfg) {
|
|
11601
|
+
this.maxAuthDelayMs = cfg.maxAuthDelayMs ?? 200;
|
|
11602
|
+
this.manifestTimerMs = cfg.manifestTimerMs ?? 20;
|
|
11603
|
+
if (!(this.maxAuthDelayMs >= 50 && this.maxAuthDelayMs <= 1e3) || !(this.manifestTimerMs >= 1)) {
|
|
11604
|
+
throw new Error("BCPV2 endpoint ignored: maxAuthDelayMs or manifestTimerMs out of range");
|
|
11605
|
+
}
|
|
11606
|
+
if (!(cfg.bandwidth > 0))
|
|
11607
|
+
throw new Error("BCPV2 endpoint ignored: protected endpoint without bandwidth");
|
|
11608
|
+
const kids = new Set(cfg.keys.map((k) => k.kid));
|
|
11609
|
+
const firsts = new Set(cfg.keys.map((k) => k.firstEpoch));
|
|
11610
|
+
if (cfg.keys.length < 1 || kids.size !== cfg.keys.length || firsts.size !== cfg.keys.length) {
|
|
11611
|
+
throw new Error("BCPV2 key set invalid: no keys, or a repeated kid or firstEpoch");
|
|
11612
|
+
}
|
|
11613
|
+
this.cfg = cfg;
|
|
11614
|
+
this.widenMs = Math.min(Math.max(cfg.widenMs ?? 0, 0), BCPV2_LEAD_BOUND_MS);
|
|
11615
|
+
this.now = cfg.now ?? Date.now;
|
|
11616
|
+
this.verifySig = cfg.verifySignature ?? ((pk, msg, sig) => {
|
|
10030
11617
|
try {
|
|
10031
|
-
|
|
10032
|
-
if (isPromiseLike(result)) {
|
|
10033
|
-
pending.push(Promise.resolve(result).then((valid) => valid, () => "error"));
|
|
10034
|
-
} else if (result) {
|
|
10035
|
-
return true;
|
|
10036
|
-
}
|
|
11618
|
+
return ed25519.verify(sig, msg, pk, { zip215: false });
|
|
10037
11619
|
} catch {
|
|
10038
|
-
|
|
10039
|
-
}
|
|
10040
|
-
}
|
|
10041
|
-
if (pending.length === 0) {
|
|
10042
|
-
if (hadSynchronousError)
|
|
10043
|
-
throw new Error("manifest signature verifier unavailable");
|
|
10044
|
-
return false;
|
|
10045
|
-
}
|
|
10046
|
-
return Promise.all(pending).then((results) => {
|
|
10047
|
-
if (results.some((valid) => valid === true))
|
|
10048
|
-
return true;
|
|
10049
|
-
if (hadSynchronousError || results.some((valid) => valid === "error")) {
|
|
10050
|
-
throw new Error("manifest signature verifier unavailable");
|
|
11620
|
+
return false;
|
|
10051
11621
|
}
|
|
10052
|
-
return false;
|
|
10053
11622
|
});
|
|
11623
|
+
this.accepted = cfg.acceptedHashAlgs ?? [BCPV2_HASH_ALG_SHA256];
|
|
11624
|
+
const bandwidth = Math.min(cfg.bandwidth, 1e10);
|
|
11625
|
+
this.queueLimit = {
|
|
11626
|
+
multicast: this.maxAuthDelayMs * bandwidth / 8e3,
|
|
11627
|
+
unicast: (this.maxAuthDelayMs + this.widenMs) * bandwidth / 8e3
|
|
11628
|
+
};
|
|
11629
|
+
const t = this.now();
|
|
11630
|
+
this.buckets = {
|
|
11631
|
+
multicast: { tokens: BUCKET_DEPTH, last: t, dropped: 0 },
|
|
11632
|
+
mirror: { tokens: BUCKET_DEPTH, last: t, dropped: 0 }
|
|
11633
|
+
};
|
|
10054
11634
|
}
|
|
10055
|
-
|
|
10056
|
-
|
|
10057
|
-
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
|
|
10063
|
-
|
|
11635
|
+
get grace() {
|
|
11636
|
+
return this.maxAuthDelayMs + 2 * this.manifestTimerMs;
|
|
11637
|
+
}
|
|
11638
|
+
/** The mirror's lead in force: 0 without a manifest track, the bound until one is measured. */
|
|
11639
|
+
get leadMs() {
|
|
11640
|
+
if (!this.cfg.applyLead)
|
|
11641
|
+
return 0;
|
|
11642
|
+
return this.lead ?? BCPV2_LEAD_BOUND_MS;
|
|
11643
|
+
}
|
|
11644
|
+
/** Step 1: a record datagram on `manifestPort`, or a record object of the manifest track. */
|
|
11645
|
+
onRecord(bytes, path) {
|
|
11646
|
+
const now = this.now();
|
|
11647
|
+
this.expire(now);
|
|
11648
|
+
const drop = (verdict) => ({ verdict, admitted: [] });
|
|
11649
|
+
const len = bytes.byteLength;
|
|
11650
|
+
if (len < BCPV2_MIN_RECORD_LENGTH || len > BCPV2_MAX_RECORD_LENGTH || (len - 132) % 32 !== 0)
|
|
11651
|
+
return drop("length");
|
|
11652
|
+
const view2 = new DataView(bytes.buffer, bytes.byteOffset, len);
|
|
11653
|
+
if (view2.getUint32(0) !== 1296583986)
|
|
11654
|
+
return drop("magic");
|
|
11655
|
+
const kid = view2.getUint32(4);
|
|
11656
|
+
const epoch = view2.getUint32(8);
|
|
11657
|
+
const mseq = view2.getBigUint64(12);
|
|
11658
|
+
const count = view2.getUint16(28);
|
|
11659
|
+
const hashAlg = bytes[30];
|
|
11660
|
+
const sent = view2.getUint32(32);
|
|
11661
|
+
const key = this.cfg.keys.find((k) => k.kid === kid);
|
|
11662
|
+
if (!key)
|
|
11663
|
+
return drop("kid");
|
|
11664
|
+
const next = Math.min(...this.cfg.keys.map((k) => k.firstEpoch).filter((f) => f > key.firstEpoch), Infinity);
|
|
11665
|
+
if (epoch < key.firstEpoch || epoch >= next)
|
|
11666
|
+
return drop("epoch");
|
|
11667
|
+
const id = `${kid}:${epoch}:${mseq}`;
|
|
11668
|
+
const seen = this.verified.get(id);
|
|
11669
|
+
if (seen) {
|
|
11670
|
+
const admitted2 = hex(sha2562(bytes)) === seen.digest ? this.arrival(seen, path, now) : [];
|
|
11671
|
+
return { verdict: "duplicate", admitted: admitted2 };
|
|
11672
|
+
}
|
|
11673
|
+
const ke = `${kid}:${epoch}`;
|
|
11674
|
+
if (this.current === null) {
|
|
11675
|
+
if (epoch < this.cfg.minEpoch || epoch < (this.cfg.pinnedEpochFloor?.get(kid) ?? 0))
|
|
11676
|
+
return drop("epoch");
|
|
11677
|
+
} else if (epoch < this.current.epoch && !this.previousAdmitted(epoch, path, now)) {
|
|
11678
|
+
return drop("epoch");
|
|
11679
|
+
}
|
|
11680
|
+
const floor = this.floor(ke, path);
|
|
11681
|
+
if (floor !== void 0 && mseq <= floor - REPLAY_WINDOW)
|
|
11682
|
+
return drop("mseq");
|
|
11683
|
+
const closed = this.closedAt.get(ke);
|
|
11684
|
+
if (closed !== void 0 && mseq > closed)
|
|
11685
|
+
return drop("closed");
|
|
11686
|
+
if (this.cfg.checkFreshness !== false) {
|
|
11687
|
+
const behind = 7e3 + this.maxAuthDelayMs + (path === "mirror" ? this.widenMs : 0);
|
|
11688
|
+
if (sent * 1e3 < now - behind || sent * 1e3 > now + 6e3)
|
|
11689
|
+
return drop("sent");
|
|
11690
|
+
}
|
|
11691
|
+
if (count !== (len - 132) / 32)
|
|
11692
|
+
return drop("count");
|
|
11693
|
+
if (!this.accepted.includes(hashAlg) || this.hashAlg !== null && hashAlg !== this.hashAlg)
|
|
11694
|
+
return drop("hash_alg");
|
|
11695
|
+
if (this.cfg.catalogCtx && !sameBytes(bytes.subarray(36, 68), this.cfg.catalogCtx))
|
|
11696
|
+
return drop("ctx");
|
|
11697
|
+
if (!this.take(path, now))
|
|
11698
|
+
return drop("budget");
|
|
11699
|
+
const record = decodeBcProvenanceV2Record(bytes);
|
|
11700
|
+
if (!this.verifySig(key.publicKey, bcProvenanceV2SignedMessage(record, this.cfg.endpoint), record.signature)) {
|
|
11701
|
+
return drop("signature");
|
|
11702
|
+
}
|
|
11703
|
+
if (this.current === null || epoch > this.current.epoch) {
|
|
11704
|
+
if (this.current !== null) {
|
|
11705
|
+
this.previous = { epoch: this.current.epoch, deadline: now + BCPV2_LEAD_BOUND_MS + this.grace };
|
|
11706
|
+
}
|
|
11707
|
+
this.current = { epoch, since: now };
|
|
11708
|
+
this.graceStart = { [path]: now };
|
|
11709
|
+
if (this.hashAlg === null) {
|
|
11710
|
+
this.hashAlg = hashAlg;
|
|
11711
|
+
for (const queue of Object.values(this.hold)) {
|
|
11712
|
+
for (const held of queue)
|
|
11713
|
+
held.digest ??= this.digest(held.datagram);
|
|
11714
|
+
}
|
|
10064
11715
|
}
|
|
11716
|
+
} else if (epoch === this.current.epoch) {
|
|
11717
|
+
this.graceStart[path] ??= now;
|
|
10065
11718
|
}
|
|
11719
|
+
const entry = {
|
|
11720
|
+
kid,
|
|
11721
|
+
epoch,
|
|
11722
|
+
mseq,
|
|
11723
|
+
path,
|
|
11724
|
+
arrival: now,
|
|
11725
|
+
sent,
|
|
11726
|
+
digest: hex(sha2562(bytes)),
|
|
11727
|
+
pairs: record.digests.map((d, i) => ({ digest: hex(d), seq: record.firstSeq + BigInt(i), admitted: false })),
|
|
11728
|
+
awaitingMulticast: path === "mirror"
|
|
11729
|
+
};
|
|
11730
|
+
this.verified.set(id, entry);
|
|
11731
|
+
this.raise(ke, path, mseq);
|
|
11732
|
+
if (record.flags & 1)
|
|
11733
|
+
this.closedAt.set(ke, mseq);
|
|
11734
|
+
const widen = path === "mirror" ? this.cfg.applyLead ? this.leadMs : this.widenMs : 0;
|
|
11735
|
+
const admitted = [];
|
|
11736
|
+
for (const pair of entry.pairs)
|
|
11737
|
+
this.handlePair(pair, now, now + this.grace + widen, now, admitted);
|
|
11738
|
+
this.dropAdmittedHeld();
|
|
11739
|
+
this.prune(now);
|
|
11740
|
+
return { verdict: "verified", admitted };
|
|
11741
|
+
}
|
|
11742
|
+
/** Step 2: a data datagram on `port` (or a packet of a listed track over MoQ unicast). */
|
|
11743
|
+
onDatagram(datagram, path) {
|
|
11744
|
+
const now = this.now();
|
|
11745
|
+
this.expire(now);
|
|
11746
|
+
if (this.hashAlg !== null) {
|
|
11747
|
+
const d = this.digest(datagram);
|
|
11748
|
+
if (this.consumePending(d, now))
|
|
11749
|
+
return { verdict: "admitted", admitted: [datagram] };
|
|
11750
|
+
if (this.admittedUntil.has(d))
|
|
11751
|
+
return { verdict: "duplicate", admitted: [] };
|
|
11752
|
+
return this.enqueue({ digest: d, datagram, expiry: 0, order: 0 }, path, now);
|
|
11753
|
+
}
|
|
11754
|
+
return this.enqueue({ datagram, expiry: 0, order: 0 }, path, now);
|
|
10066
11755
|
}
|
|
10067
|
-
|
|
10068
|
-
|
|
10069
|
-
|
|
10070
|
-
|
|
10071
|
-
|
|
10072
|
-
|
|
10073
|
-
|
|
10074
|
-
|
|
10075
|
-
this
|
|
11756
|
+
/**
|
|
11757
|
+
* A source packet recovered by FEC decode, its base SS_ID (SS_Start + ESI)
|
|
11758
|
+
* appended: admitted only on a pending entry it consumes, never held. One no
|
|
11759
|
+
* verified record lists, or a copy of an admitted packet, is dropped.
|
|
11760
|
+
*/
|
|
11761
|
+
admitRecovered(datagram) {
|
|
11762
|
+
const now = this.now();
|
|
11763
|
+
this.expire(now);
|
|
11764
|
+
return this.hashAlg !== null && this.consumePending(this.digest(datagram), now);
|
|
11765
|
+
}
|
|
11766
|
+
/**
|
|
11767
|
+
* Discard the per-flow state on a `streamId` change or a key-set change that fails the
|
|
11768
|
+
* flow's current (kid, epoch): budgets and hold queues survive, held digests are cleared.
|
|
11769
|
+
*/
|
|
11770
|
+
resetGeneration() {
|
|
11771
|
+
this.current = null;
|
|
11772
|
+
this.previous = null;
|
|
11773
|
+
this.graceStart = {};
|
|
11774
|
+
this.hashAlg = null;
|
|
11775
|
+
this.verified.clear();
|
|
11776
|
+
this.highest = { multicast: /* @__PURE__ */ new Map(), mirror: /* @__PURE__ */ new Map() };
|
|
11777
|
+
this.closedAt.clear();
|
|
11778
|
+
this.lead = null;
|
|
11779
|
+
this.pending.clear();
|
|
11780
|
+
this.admittedUntil.clear();
|
|
11781
|
+
for (const queue of Object.values(this.hold))
|
|
11782
|
+
for (const held of queue)
|
|
11783
|
+
held.digest = void 0;
|
|
11784
|
+
}
|
|
11785
|
+
/** The receiver ceased to hold the endpoint: drop everything; no drop here is an expiry. */
|
|
11786
|
+
release() {
|
|
11787
|
+
this.resetGeneration();
|
|
11788
|
+
this.hold = { multicast: [], unicast: [] };
|
|
11789
|
+
this.holdBytes = { multicast: 0, unicast: 0 };
|
|
10076
11790
|
}
|
|
10077
|
-
|
|
10078
|
-
|
|
11791
|
+
digest(datagram) {
|
|
11792
|
+
return hex(bcProvenanceV2DatagramDigest(this.cfg.endpoint, datagram));
|
|
11793
|
+
}
|
|
11794
|
+
/** Consume the lowest-seq pending entry for `digest`, admitting it. */
|
|
11795
|
+
consumePending(digest, now) {
|
|
11796
|
+
const list = this.pending.get(digest);
|
|
11797
|
+
if (!list?.length)
|
|
10079
11798
|
return false;
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
11799
|
+
list.sort((a, b) => a.pair.seq < b.pair.seq ? -1 : a.pair.seq > b.pair.seq ? 1 : 0);
|
|
11800
|
+
const hit = list.shift();
|
|
11801
|
+
if (list.length === 0)
|
|
11802
|
+
this.pending.delete(digest);
|
|
11803
|
+
hit.pair.pending = void 0;
|
|
11804
|
+
hit.pair.admitted = true;
|
|
11805
|
+
this.admittedUntil.set(digest, now + this.maxAuthDelayMs + this.leadMs);
|
|
10085
11806
|
return true;
|
|
10086
11807
|
}
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
10092
|
-
|
|
10093
|
-
|
|
10094
|
-
|
|
10095
|
-
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
*
|
|
10106
|
-
* Deliberately NOT used by `#failOpenGroup`/`#failOpenTrack` — failing open on
|
|
10107
|
-
* a genuine verifier fault is correct and stays untouched.
|
|
10108
|
-
*/
|
|
10109
|
-
#giveUpOnPending(pending) {
|
|
10110
|
-
if (this.#config.mode !== "enforce") {
|
|
10111
|
-
pending.release();
|
|
10112
|
-
return;
|
|
11808
|
+
enqueue(held, path, now) {
|
|
11809
|
+
if (this.holdBytes[path] + held.datagram.byteLength > this.queueLimit[path]) {
|
|
11810
|
+
return { verdict: "overflow", admitted: [] };
|
|
11811
|
+
}
|
|
11812
|
+
held.expiry = now + this.maxAuthDelayMs + (path === "unicast" ? this.widenMs : 0);
|
|
11813
|
+
held.order = this.order++;
|
|
11814
|
+
this.hold[path].push(held);
|
|
11815
|
+
this.holdBytes[path] += held.datagram.byteLength;
|
|
11816
|
+
return { verdict: "held", admitted: [] };
|
|
11817
|
+
}
|
|
11818
|
+
/** Remove and return the oldest held datagram with `digest`, across both queues. */
|
|
11819
|
+
takeHeld(digest) {
|
|
11820
|
+
let best;
|
|
11821
|
+
for (const path of ["multicast", "unicast"]) {
|
|
11822
|
+
const index = this.hold[path].findIndex((h) => h.digest === digest);
|
|
11823
|
+
if (index >= 0 && (!best || this.hold[path][index].order < best.order)) {
|
|
11824
|
+
best = { path, index, order: this.hold[path][index].order };
|
|
11825
|
+
}
|
|
10113
11826
|
}
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
this
|
|
11827
|
+
if (!best)
|
|
11828
|
+
return void 0;
|
|
11829
|
+
const [held] = this.hold[best.path].splice(best.index, 1);
|
|
11830
|
+
this.holdBytes[best.path] -= held.datagram.byteLength;
|
|
11831
|
+
return held.datagram;
|
|
11832
|
+
}
|
|
11833
|
+
dropAdmittedHeld() {
|
|
11834
|
+
for (const path of ["multicast", "unicast"]) {
|
|
11835
|
+
this.hold[path] = this.hold[path].filter((h) => {
|
|
11836
|
+
const keep = h.digest === void 0 || !this.admittedUntil.has(h.digest);
|
|
11837
|
+
if (!keep)
|
|
11838
|
+
this.holdBytes[path] -= h.datagram.byteLength;
|
|
11839
|
+
return keep;
|
|
11840
|
+
});
|
|
10123
11841
|
}
|
|
10124
11842
|
}
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
11843
|
+
/** Step 1 pair handling: admit a held copy, or insert a pending entry. */
|
|
11844
|
+
handlePair(pair, now, expiry, inserted, out) {
|
|
11845
|
+
const datagram = this.takeHeld(pair.digest);
|
|
11846
|
+
if (datagram) {
|
|
11847
|
+
pair.admitted = true;
|
|
11848
|
+
this.admittedUntil.set(pair.digest, now + this.maxAuthDelayMs + this.leadMs);
|
|
11849
|
+
out.push(datagram);
|
|
10129
11850
|
return;
|
|
10130
11851
|
}
|
|
10131
|
-
|
|
10132
|
-
|
|
10133
|
-
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
11852
|
+
const entry = { pair, inserted, expiry };
|
|
11853
|
+
pair.pending = entry;
|
|
11854
|
+
const list = this.pending.get(pair.digest);
|
|
11855
|
+
if (list)
|
|
11856
|
+
list.push(entry);
|
|
11857
|
+
else
|
|
11858
|
+
this.pending.set(pair.digest, [entry]);
|
|
11859
|
+
}
|
|
11860
|
+
/** A byte-identical copy dropped by the already-verified lookup. */
|
|
11861
|
+
arrival(seen, path, now) {
|
|
11862
|
+
const ke = `${seen.kid}:${seen.epoch}`;
|
|
11863
|
+
this.raise(ke, path, seen.mseq);
|
|
11864
|
+
if (this.current && seen.epoch === this.current.epoch)
|
|
11865
|
+
this.graceStart[path] ??= now;
|
|
11866
|
+
if (path !== "multicast" || !seen.awaitingMulticast)
|
|
11867
|
+
return [];
|
|
11868
|
+
seen.awaitingMulticast = false;
|
|
11869
|
+
if (!this.cfg.applyLead)
|
|
11870
|
+
return [];
|
|
11871
|
+
const t = this.manifestTimerMs;
|
|
11872
|
+
const interval = Math.min(Math.ceil((now - seen.arrival) / t) * t, BCPV2_LEAD_BOUND_MS);
|
|
11873
|
+
if (this.lead === null) {
|
|
11874
|
+
this.lead = interval;
|
|
11875
|
+
return [];
|
|
11876
|
+
}
|
|
11877
|
+
if (interval <= this.lead)
|
|
11878
|
+
return [];
|
|
11879
|
+
this.lead = interval;
|
|
11880
|
+
const out = [];
|
|
11881
|
+
const records = [seen, ...[...this.verified.values()].filter((v) => v.awaitingMulticast && v.arrival >= now - interval)];
|
|
11882
|
+
for (const v of records) {
|
|
11883
|
+
for (const pair of v.pairs) {
|
|
11884
|
+
if (pair.admitted) {
|
|
11885
|
+
this.admittedUntil.set(pair.digest, now + this.maxAuthDelayMs + interval);
|
|
11886
|
+
} else if (pair.pending) {
|
|
11887
|
+
pair.pending.expiry = pair.pending.inserted + this.grace + interval;
|
|
11888
|
+
} else {
|
|
11889
|
+
this.handlePair(pair, now, now + this.grace + interval, now, out);
|
|
11890
|
+
}
|
|
10146
11891
|
}
|
|
10147
11892
|
}
|
|
11893
|
+
this.dropAdmittedHeld();
|
|
11894
|
+
return out;
|
|
10148
11895
|
}
|
|
10149
|
-
|
|
10150
|
-
this
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10158
|
-
|
|
10159
|
-
|
|
10160
|
-
|
|
10161
|
-
|
|
10162
|
-
|
|
10163
|
-
|
|
10164
|
-
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10171
|
-
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
|
|
10183
|
-
output += BASE64URL_ALPHABET[(b1 & 15) << 2 | (b2 === void 0 ? 0 : b2 >> 6)];
|
|
10184
|
-
if (b2 === void 0) break;
|
|
10185
|
-
output += BASE64URL_ALPHABET[b2 & 63];
|
|
10186
|
-
}
|
|
10187
|
-
return output;
|
|
10188
|
-
}
|
|
10189
|
-
var BASE64URL_DECODE_TABLE = (() => {
|
|
10190
|
-
const table = new Int8Array(128).fill(-1);
|
|
10191
|
-
for (let i = 0; i < BASE64URL_ALPHABET.length; i++) {
|
|
10192
|
-
table[BASE64URL_ALPHABET.charCodeAt(i)] = i;
|
|
10193
|
-
}
|
|
10194
|
-
return table;
|
|
10195
|
-
})();
|
|
10196
|
-
function decodeBase64Url(text2) {
|
|
10197
|
-
if (text2.length % 4 === 1) {
|
|
10198
|
-
throw new Error(`[multicast-auth-catalog] invalid unpadded base64url length for "${text2}"`);
|
|
10199
|
-
}
|
|
10200
|
-
const bytes = [];
|
|
10201
|
-
let buffer = 0;
|
|
10202
|
-
let bits = 0;
|
|
10203
|
-
for (let i = 0; i < text2.length; i++) {
|
|
10204
|
-
const code = text2.charCodeAt(i);
|
|
10205
|
-
const value = code < 128 ? BASE64URL_DECODE_TABLE[code] : -1;
|
|
10206
|
-
if (value === void 0 || value < 0) {
|
|
10207
|
-
throw new Error(`[multicast-auth-catalog] invalid base64url character in "${text2}"`);
|
|
10208
|
-
}
|
|
10209
|
-
buffer = buffer << 6 | value;
|
|
10210
|
-
bits += 6;
|
|
10211
|
-
if (bits >= 8) {
|
|
10212
|
-
bits -= 8;
|
|
10213
|
-
bytes.push(buffer >> bits & 255);
|
|
10214
|
-
}
|
|
10215
|
-
}
|
|
10216
|
-
const decoded = Uint8Array.from(bytes);
|
|
10217
|
-
if (encodeBase64Url(decoded) !== text2) {
|
|
10218
|
-
throw new Error(`[multicast-auth-catalog] non-canonical base64url encoding "${text2}"`);
|
|
10219
|
-
}
|
|
10220
|
-
return decoded;
|
|
10221
|
-
}
|
|
10222
|
-
function decodeEd25519PublicKey(publicKey) {
|
|
10223
|
-
const bytes = decodeBase64Url(publicKey);
|
|
10224
|
-
if (bytes.byteLength !== RAW_ED25519_KEY_LENGTH) {
|
|
10225
|
-
throw new Error(
|
|
10226
|
-
`[multicast-auth-catalog] public key must decode to ${RAW_ED25519_KEY_LENGTH} raw bytes, got ${bytes.byteLength}`
|
|
10227
|
-
);
|
|
10228
|
-
}
|
|
10229
|
-
return bytes;
|
|
10230
|
-
}
|
|
10231
|
-
function resolveMulticastAuthCatalog(catalog, options = {}) {
|
|
10232
|
-
if (typeof catalog !== "object" || catalog === null || Array.isArray(catalog)) {
|
|
10233
|
-
throw new Error("[multicast-auth-catalog] catalog must be an object");
|
|
11896
|
+
previousAdmitted(epoch, path, now) {
|
|
11897
|
+
if (!this.previous || epoch !== this.previous.epoch)
|
|
11898
|
+
return false;
|
|
11899
|
+
const m = this.graceStart.multicast;
|
|
11900
|
+
if (path === "multicast")
|
|
11901
|
+
return m === void 0 || now <= m + this.grace;
|
|
11902
|
+
const starts = [m, this.graceStart.mirror].filter((s) => s !== void 0);
|
|
11903
|
+
return starts.length > 0 && now <= Math.min(...starts) + this.grace;
|
|
11904
|
+
}
|
|
11905
|
+
/** The replay floor this record meets: its path's, or the higher of both from the mirror. */
|
|
11906
|
+
floor(ke, path) {
|
|
11907
|
+
const m = this.highest.multicast.get(ke);
|
|
11908
|
+
if (path === "multicast")
|
|
11909
|
+
return m;
|
|
11910
|
+
const r = this.highest.mirror.get(ke);
|
|
11911
|
+
if (m === void 0)
|
|
11912
|
+
return r;
|
|
11913
|
+
return r === void 0 || m > r ? m : r;
|
|
11914
|
+
}
|
|
11915
|
+
raise(ke, path, mseq) {
|
|
11916
|
+
const h = this.highest[path].get(ke);
|
|
11917
|
+
if (h === void 0 || mseq > h)
|
|
11918
|
+
this.highest[path].set(ke, mseq);
|
|
11919
|
+
}
|
|
11920
|
+
take(path, now) {
|
|
11921
|
+
const b = this.buckets[path];
|
|
11922
|
+
b.tokens = Math.min(BUCKET_DEPTH, b.tokens + (now - b.last) * BUCKET_RATE_PER_MS);
|
|
11923
|
+
b.last = now;
|
|
11924
|
+
if (b.tokens < 1) {
|
|
11925
|
+
b.dropped++;
|
|
11926
|
+
return false;
|
|
11927
|
+
}
|
|
11928
|
+
b.tokens -= 1;
|
|
11929
|
+
return true;
|
|
10234
11930
|
}
|
|
10235
|
-
|
|
10236
|
-
|
|
10237
|
-
|
|
10238
|
-
|
|
10239
|
-
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
11931
|
+
expire(now) {
|
|
11932
|
+
for (const path of ["multicast", "unicast"]) {
|
|
11933
|
+
this.hold[path] = this.hold[path].filter((h) => {
|
|
11934
|
+
if (h.expiry > now)
|
|
11935
|
+
return true;
|
|
11936
|
+
this.holdBytes[path] -= h.datagram.byteLength;
|
|
11937
|
+
this.expired[path]++;
|
|
11938
|
+
return false;
|
|
11939
|
+
});
|
|
10243
11940
|
}
|
|
10244
|
-
|
|
11941
|
+
let keepFrom = null;
|
|
11942
|
+
for (const [d, list] of this.pending) {
|
|
11943
|
+
const live = list.filter((p) => {
|
|
11944
|
+
if (p.expiry > now)
|
|
11945
|
+
return true;
|
|
11946
|
+
if (keepFrom === null) {
|
|
11947
|
+
const age = this.keepPendingAgeMs?.();
|
|
11948
|
+
keepFrom = age === void 0 ? void 0 : now - age;
|
|
11949
|
+
}
|
|
11950
|
+
if (keepFrom !== void 0 && keepFrom !== null && p.expiry > keepFrom)
|
|
11951
|
+
return true;
|
|
11952
|
+
p.pair.pending = void 0;
|
|
11953
|
+
return false;
|
|
11954
|
+
});
|
|
11955
|
+
if (live.length)
|
|
11956
|
+
this.pending.set(d, live);
|
|
11957
|
+
else
|
|
11958
|
+
this.pending.delete(d);
|
|
11959
|
+
}
|
|
11960
|
+
for (const [d, until] of this.admittedUntil)
|
|
11961
|
+
if (until <= now)
|
|
11962
|
+
this.admittedUntil.delete(d);
|
|
11963
|
+
if (this.previous && now > this.previous.deadline)
|
|
11964
|
+
this.previous = null;
|
|
10245
11965
|
}
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
|
|
10254
|
-
|
|
10255
|
-
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
10261
|
-
|
|
10262
|
-
...flowAuth.manifestTrack === void 0 ? {} : { manifestTrack: flowAuth.manifestTrack },
|
|
10263
|
-
tracks: (endpoint["tracks"] ?? []).map(({ name, packetId }) => ({
|
|
10264
|
-
name,
|
|
10265
|
-
packetId
|
|
10266
|
-
}))
|
|
10267
|
-
});
|
|
10268
|
-
});
|
|
10269
|
-
return {
|
|
10270
|
-
keys: auth.keys.map((key) => ({ kid: key.kid, publicKey: decodeEd25519PublicKey(key.publicKey), firstEpoch: key.firstEpoch })).sort((a, b) => a.firstEpoch - b.firstEpoch),
|
|
10271
|
-
minEpoch: auth.minEpoch,
|
|
10272
|
-
flows
|
|
10273
|
-
};
|
|
10274
|
-
}
|
|
10275
|
-
function multicastAuthKeyFor(resolved, kid, epoch) {
|
|
10276
|
-
return manifestKeyFor(resolved.keys, epoch, kid);
|
|
10277
|
-
}
|
|
10278
|
-
|
|
10279
|
-
// src/manifest-auth-plan.ts
|
|
10280
|
-
function createManifestAuthPlan(catalog, options = {}) {
|
|
10281
|
-
const resolved = resolveMulticastAuthCatalog(catalog, options);
|
|
10282
|
-
if (!resolved) return void 0;
|
|
10283
|
-
const byManifestTrack = /* @__PURE__ */ new Map();
|
|
10284
|
-
for (const flow of resolved.flows) {
|
|
10285
|
-
if (flow.manifestTrack !== void 0) byManifestTrack.set(flow.manifestTrack, flow);
|
|
11966
|
+
/**
|
|
11967
|
+
* Retire verified entries below their arrival path's replay floor, keeping a mirrored entry
|
|
11968
|
+
* while the freshness check would still pass its copy on `manifestPort`.
|
|
11969
|
+
* ponytail: linear scan per record; index by (kid, epoch) if retained sets grow past a few thousand.
|
|
11970
|
+
*/
|
|
11971
|
+
prune(now) {
|
|
11972
|
+
const retention = 7e3 + this.maxAuthDelayMs;
|
|
11973
|
+
for (const [id, v] of this.verified) {
|
|
11974
|
+
const h = this.highest[v.path].get(`${v.kid}:${v.epoch}`);
|
|
11975
|
+
const aboveFloor = h === void 0 || v.mseq > h - REPLAY_WINDOW;
|
|
11976
|
+
const fresh = this.cfg.checkFreshness === false ? v.arrival + retention >= now : v.sent * 1e3 + retention >= now;
|
|
11977
|
+
const current = this.current && (v.epoch === this.current.epoch || v.epoch === this.previous?.epoch);
|
|
11978
|
+
if (current && (aboveFloor || v.path === "mirror" && fresh))
|
|
11979
|
+
continue;
|
|
11980
|
+
this.verified.delete(id);
|
|
11981
|
+
}
|
|
10286
11982
|
}
|
|
10287
|
-
|
|
10288
|
-
keys: resolved.keys,
|
|
10289
|
-
minEpoch: resolved.minEpoch,
|
|
10290
|
-
flows: resolved.flows,
|
|
10291
|
-
manifestTracks: [...byManifestTrack.keys()],
|
|
10292
|
-
keyFor: (kid, epoch) => multicastAuthKeyFor(resolved, kid, epoch),
|
|
10293
|
-
flowForManifestPort: (source, groupAddress, manifestPort) => resolved.flows.find((flow) => flow.source === source && flow.groupAddress === groupAddress && flow.manifestPort === manifestPort),
|
|
10294
|
-
flowForManifestTrack: (manifestTrack) => byManifestTrack.get(manifestTrack)
|
|
10295
|
-
};
|
|
10296
|
-
}
|
|
11983
|
+
};
|
|
10297
11984
|
export {
|
|
11985
|
+
BcProvenanceV2Receiver,
|
|
10298
11986
|
CmsfCatalogValidationError,
|
|
10299
11987
|
FEC_INACTIVE_REASONS,
|
|
10300
|
-
ManifestVerifier,
|
|
10301
11988
|
MmtpContainerParser,
|
|
10302
11989
|
MmtpFecSession,
|
|
10303
11990
|
MmtpToCmaf,
|
|
@@ -10305,14 +11992,11 @@ export {
|
|
|
10305
11992
|
catalogAtsc3NetworkSource,
|
|
10306
11993
|
catalogDeclaresFec,
|
|
10307
11994
|
catalogFecInterleaveMs,
|
|
10308
|
-
createManifestAuthPlan,
|
|
10309
11995
|
createWasmMmtpContainerParser,
|
|
10310
|
-
createWebCryptoEd25519Verifier,
|
|
10311
11996
|
datagramMfuReassembly,
|
|
10312
11997
|
fecBlockBudgetMs2 as fecBlockBudgetMs,
|
|
10313
11998
|
fecBlockDeadlineMs,
|
|
10314
11999
|
isFmp4InitSegment,
|
|
10315
|
-
manifestBindingId,
|
|
10316
12000
|
mmtpFrameReorderWindowFrames,
|
|
10317
12001
|
reliableMoqMfuReassembly,
|
|
10318
12002
|
resolveFecState,
|
|
@@ -10323,5 +12007,12 @@ export {
|
|
|
10323
12007
|
|
|
10324
12008
|
@noble/hashes/esm/utils.js:
|
|
10325
12009
|
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
12010
|
+
|
|
12011
|
+
@noble/curves/esm/utils.js:
|
|
12012
|
+
@noble/curves/esm/abstract/modular.js:
|
|
12013
|
+
@noble/curves/esm/abstract/curve.js:
|
|
12014
|
+
@noble/curves/esm/abstract/edwards.js:
|
|
12015
|
+
@noble/curves/esm/ed25519.js:
|
|
12016
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
10326
12017
|
*/
|
|
10327
12018
|
//# sourceMappingURL=no-modules.js.map
|