@themoltnet/legreffier 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2331 -1538
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { useState, useEffect, useReducer, useRef } from "react";
|
|
|
7
7
|
import figlet from "figlet";
|
|
8
8
|
import { readFile, writeFile, mkdir, chmod, rm } from "node:fs/promises";
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
|
-
import {
|
|
10
|
+
import { randomBytes as randomBytes$2, createHash } from "crypto";
|
|
11
11
|
import { parse, stringify } from "smol-toml";
|
|
12
12
|
import open from "open";
|
|
13
13
|
const colors = {
|
|
@@ -350,13 +350,13 @@ function CliSummaryBox({
|
|
|
350
350
|
}
|
|
351
351
|
) });
|
|
352
352
|
}
|
|
353
|
-
const jsonBodySerializer
|
|
353
|
+
const jsonBodySerializer = {
|
|
354
354
|
bodySerializer: (body) => JSON.stringify(
|
|
355
355
|
body,
|
|
356
356
|
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
357
357
|
)
|
|
358
358
|
};
|
|
359
|
-
const createSseClient
|
|
359
|
+
const createSseClient = ({
|
|
360
360
|
onRequest,
|
|
361
361
|
onSseError,
|
|
362
362
|
onSseEvent,
|
|
@@ -490,7 +490,7 @@ const createSseClient$1 = ({
|
|
|
490
490
|
const stream = createStream();
|
|
491
491
|
return { stream };
|
|
492
492
|
};
|
|
493
|
-
const separatorArrayExplode
|
|
493
|
+
const separatorArrayExplode = (style) => {
|
|
494
494
|
switch (style) {
|
|
495
495
|
case "label":
|
|
496
496
|
return ".";
|
|
@@ -502,7 +502,7 @@ const separatorArrayExplode$1 = (style) => {
|
|
|
502
502
|
return "&";
|
|
503
503
|
}
|
|
504
504
|
};
|
|
505
|
-
const separatorArrayNoExplode
|
|
505
|
+
const separatorArrayNoExplode = (style) => {
|
|
506
506
|
switch (style) {
|
|
507
507
|
case "form":
|
|
508
508
|
return ",";
|
|
@@ -514,7 +514,7 @@ const separatorArrayNoExplode$1 = (style) => {
|
|
|
514
514
|
return ",";
|
|
515
515
|
}
|
|
516
516
|
};
|
|
517
|
-
const separatorObjectExplode
|
|
517
|
+
const separatorObjectExplode = (style) => {
|
|
518
518
|
switch (style) {
|
|
519
519
|
case "label":
|
|
520
520
|
return ".";
|
|
@@ -526,7 +526,7 @@ const separatorObjectExplode$1 = (style) => {
|
|
|
526
526
|
return "&";
|
|
527
527
|
}
|
|
528
528
|
};
|
|
529
|
-
const serializeArrayParam
|
|
529
|
+
const serializeArrayParam = ({
|
|
530
530
|
allowReserved,
|
|
531
531
|
explode,
|
|
532
532
|
name: name2,
|
|
@@ -534,7 +534,7 @@ const serializeArrayParam$1 = ({
|
|
|
534
534
|
value
|
|
535
535
|
}) => {
|
|
536
536
|
if (!explode) {
|
|
537
|
-
const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode
|
|
537
|
+
const joinedValues2 = (allowReserved ? value : value.map((v) => encodeURIComponent(v))).join(separatorArrayNoExplode(style));
|
|
538
538
|
switch (style) {
|
|
539
539
|
case "label":
|
|
540
540
|
return `.${joinedValues2}`;
|
|
@@ -546,12 +546,12 @@ const serializeArrayParam$1 = ({
|
|
|
546
546
|
return `${name2}=${joinedValues2}`;
|
|
547
547
|
}
|
|
548
548
|
}
|
|
549
|
-
const separator = separatorArrayExplode
|
|
549
|
+
const separator = separatorArrayExplode(style);
|
|
550
550
|
const joinedValues = value.map((v) => {
|
|
551
551
|
if (style === "label" || style === "simple") {
|
|
552
552
|
return allowReserved ? v : encodeURIComponent(v);
|
|
553
553
|
}
|
|
554
|
-
return serializePrimitiveParam
|
|
554
|
+
return serializePrimitiveParam({
|
|
555
555
|
allowReserved,
|
|
556
556
|
name: name2,
|
|
557
557
|
value: v
|
|
@@ -559,7 +559,7 @@ const serializeArrayParam$1 = ({
|
|
|
559
559
|
}).join(separator);
|
|
560
560
|
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
561
561
|
};
|
|
562
|
-
const serializePrimitiveParam
|
|
562
|
+
const serializePrimitiveParam = ({
|
|
563
563
|
allowReserved,
|
|
564
564
|
name: name2,
|
|
565
565
|
value
|
|
@@ -574,7 +574,7 @@ const serializePrimitiveParam$1 = ({
|
|
|
574
574
|
}
|
|
575
575
|
return `${name2}=${allowReserved ? value : encodeURIComponent(value)}`;
|
|
576
576
|
};
|
|
577
|
-
const serializeObjectParam
|
|
577
|
+
const serializeObjectParam = ({
|
|
578
578
|
allowReserved,
|
|
579
579
|
explode,
|
|
580
580
|
name: name2,
|
|
@@ -606,9 +606,9 @@ const serializeObjectParam$1 = ({
|
|
|
606
606
|
return joinedValues2;
|
|
607
607
|
}
|
|
608
608
|
}
|
|
609
|
-
const separator = separatorObjectExplode
|
|
609
|
+
const separator = separatorObjectExplode(style);
|
|
610
610
|
const joinedValues = Object.entries(value).map(
|
|
611
|
-
([key, v]) => serializePrimitiveParam
|
|
611
|
+
([key, v]) => serializePrimitiveParam({
|
|
612
612
|
allowReserved,
|
|
613
613
|
name: style === "deepObject" ? `${name2}[${key}]` : key,
|
|
614
614
|
value: v
|
|
@@ -616,10 +616,10 @@ const serializeObjectParam$1 = ({
|
|
|
616
616
|
).join(separator);
|
|
617
617
|
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
618
618
|
};
|
|
619
|
-
const PATH_PARAM_RE
|
|
620
|
-
const defaultPathSerializer
|
|
619
|
+
const PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
620
|
+
const defaultPathSerializer = ({ path, url: _url }) => {
|
|
621
621
|
let url = _url;
|
|
622
|
-
const matches = _url.match(PATH_PARAM_RE
|
|
622
|
+
const matches = _url.match(PATH_PARAM_RE);
|
|
623
623
|
if (matches) {
|
|
624
624
|
for (const match of matches) {
|
|
625
625
|
let explode = false;
|
|
@@ -643,14 +643,14 @@ const defaultPathSerializer$1 = ({ path, url: _url }) => {
|
|
|
643
643
|
if (Array.isArray(value)) {
|
|
644
644
|
url = url.replace(
|
|
645
645
|
match,
|
|
646
|
-
serializeArrayParam
|
|
646
|
+
serializeArrayParam({ explode, name: name2, style, value })
|
|
647
647
|
);
|
|
648
648
|
continue;
|
|
649
649
|
}
|
|
650
650
|
if (typeof value === "object") {
|
|
651
651
|
url = url.replace(
|
|
652
652
|
match,
|
|
653
|
-
serializeObjectParam
|
|
653
|
+
serializeObjectParam({
|
|
654
654
|
explode,
|
|
655
655
|
name: name2,
|
|
656
656
|
style,
|
|
@@ -663,7 +663,7 @@ const defaultPathSerializer$1 = ({ path, url: _url }) => {
|
|
|
663
663
|
if (style === "matrix") {
|
|
664
664
|
url = url.replace(
|
|
665
665
|
match,
|
|
666
|
-
`;${serializePrimitiveParam
|
|
666
|
+
`;${serializePrimitiveParam({
|
|
667
667
|
name: name2,
|
|
668
668
|
value
|
|
669
669
|
})}`
|
|
@@ -678,7 +678,7 @@ const defaultPathSerializer$1 = ({ path, url: _url }) => {
|
|
|
678
678
|
}
|
|
679
679
|
return url;
|
|
680
680
|
};
|
|
681
|
-
const getUrl
|
|
681
|
+
const getUrl = ({
|
|
682
682
|
baseUrl,
|
|
683
683
|
path,
|
|
684
684
|
query,
|
|
@@ -688,7 +688,7 @@ const getUrl$1 = ({
|
|
|
688
688
|
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
689
689
|
let url = (baseUrl ?? "") + pathUrl;
|
|
690
690
|
if (path) {
|
|
691
|
-
url = defaultPathSerializer
|
|
691
|
+
url = defaultPathSerializer({ path, url });
|
|
692
692
|
}
|
|
693
693
|
let search = query ? querySerializer(query) : "";
|
|
694
694
|
if (search.startsWith("?")) {
|
|
@@ -699,7 +699,7 @@ const getUrl$1 = ({
|
|
|
699
699
|
}
|
|
700
700
|
return url;
|
|
701
701
|
};
|
|
702
|
-
function getValidRequestBody
|
|
702
|
+
function getValidRequestBody(options) {
|
|
703
703
|
const hasBody = options.body !== void 0;
|
|
704
704
|
const isSerializedBody = hasBody && options.bodySerializer;
|
|
705
705
|
if (isSerializedBody) {
|
|
@@ -714,7 +714,7 @@ function getValidRequestBody$1(options) {
|
|
|
714
714
|
}
|
|
715
715
|
return void 0;
|
|
716
716
|
}
|
|
717
|
-
const getAuthToken
|
|
717
|
+
const getAuthToken = async (auth, callback) => {
|
|
718
718
|
const token = typeof callback === "function" ? await callback(auth) : callback;
|
|
719
719
|
if (!token) {
|
|
720
720
|
return;
|
|
@@ -727,7 +727,7 @@ const getAuthToken$1 = async (auth, callback) => {
|
|
|
727
727
|
}
|
|
728
728
|
return token;
|
|
729
729
|
};
|
|
730
|
-
const createQuerySerializer
|
|
730
|
+
const createQuerySerializer = ({
|
|
731
731
|
parameters = {},
|
|
732
732
|
...args
|
|
733
733
|
} = {}) => {
|
|
@@ -741,7 +741,7 @@ const createQuerySerializer$1 = ({
|
|
|
741
741
|
}
|
|
742
742
|
const options = parameters[name2] || args;
|
|
743
743
|
if (Array.isArray(value)) {
|
|
744
|
-
const serializedArray = serializeArrayParam
|
|
744
|
+
const serializedArray = serializeArrayParam({
|
|
745
745
|
allowReserved: options.allowReserved,
|
|
746
746
|
explode: true,
|
|
747
747
|
name: name2,
|
|
@@ -751,7 +751,7 @@ const createQuerySerializer$1 = ({
|
|
|
751
751
|
});
|
|
752
752
|
if (serializedArray) search.push(serializedArray);
|
|
753
753
|
} else if (typeof value === "object") {
|
|
754
|
-
const serializedObject = serializeObjectParam
|
|
754
|
+
const serializedObject = serializeObjectParam({
|
|
755
755
|
allowReserved: options.allowReserved,
|
|
756
756
|
explode: true,
|
|
757
757
|
name: name2,
|
|
@@ -761,7 +761,7 @@ const createQuerySerializer$1 = ({
|
|
|
761
761
|
});
|
|
762
762
|
if (serializedObject) search.push(serializedObject);
|
|
763
763
|
} else {
|
|
764
|
-
const serializedPrimitive = serializePrimitiveParam
|
|
764
|
+
const serializedPrimitive = serializePrimitiveParam({
|
|
765
765
|
allowReserved: options.allowReserved,
|
|
766
766
|
name: name2,
|
|
767
767
|
value
|
|
@@ -774,7 +774,7 @@ const createQuerySerializer$1 = ({
|
|
|
774
774
|
};
|
|
775
775
|
return querySerializer;
|
|
776
776
|
};
|
|
777
|
-
const getParseAs
|
|
777
|
+
const getParseAs = (contentType) => {
|
|
778
778
|
if (!contentType) {
|
|
779
779
|
return "stream";
|
|
780
780
|
}
|
|
@@ -798,7 +798,7 @@ const getParseAs$1 = (contentType) => {
|
|
|
798
798
|
}
|
|
799
799
|
return;
|
|
800
800
|
};
|
|
801
|
-
const checkForExistence
|
|
801
|
+
const checkForExistence = (options, name2) => {
|
|
802
802
|
if (!name2) {
|
|
803
803
|
return false;
|
|
804
804
|
}
|
|
@@ -807,15 +807,15 @@ const checkForExistence$1 = (options, name2) => {
|
|
|
807
807
|
}
|
|
808
808
|
return false;
|
|
809
809
|
};
|
|
810
|
-
const setAuthParams
|
|
810
|
+
const setAuthParams = async ({
|
|
811
811
|
security,
|
|
812
812
|
...options
|
|
813
813
|
}) => {
|
|
814
814
|
for (const auth of security) {
|
|
815
|
-
if (checkForExistence
|
|
815
|
+
if (checkForExistence(options, auth.name)) {
|
|
816
816
|
continue;
|
|
817
817
|
}
|
|
818
|
-
const token = await getAuthToken
|
|
818
|
+
const token = await getAuthToken(auth, options.auth);
|
|
819
819
|
if (!token) {
|
|
820
820
|
continue;
|
|
821
821
|
}
|
|
@@ -837,35 +837,35 @@ const setAuthParams$1 = async ({
|
|
|
837
837
|
}
|
|
838
838
|
}
|
|
839
839
|
};
|
|
840
|
-
const buildUrl
|
|
840
|
+
const buildUrl = (options) => getUrl({
|
|
841
841
|
baseUrl: options.baseUrl,
|
|
842
842
|
path: options.path,
|
|
843
843
|
query: options.query,
|
|
844
|
-
querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer
|
|
844
|
+
querySerializer: typeof options.querySerializer === "function" ? options.querySerializer : createQuerySerializer(options.querySerializer),
|
|
845
845
|
url: options.url
|
|
846
846
|
});
|
|
847
|
-
const mergeConfigs
|
|
847
|
+
const mergeConfigs = (a, b) => {
|
|
848
848
|
const config = { ...a, ...b };
|
|
849
849
|
if (config.baseUrl?.endsWith("/")) {
|
|
850
850
|
config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);
|
|
851
851
|
}
|
|
852
|
-
config.headers = mergeHeaders
|
|
852
|
+
config.headers = mergeHeaders(a.headers, b.headers);
|
|
853
853
|
return config;
|
|
854
854
|
};
|
|
855
|
-
const headersEntries
|
|
855
|
+
const headersEntries = (headers) => {
|
|
856
856
|
const entries = [];
|
|
857
857
|
headers.forEach((value, key) => {
|
|
858
858
|
entries.push([key, value]);
|
|
859
859
|
});
|
|
860
860
|
return entries;
|
|
861
861
|
};
|
|
862
|
-
const mergeHeaders
|
|
862
|
+
const mergeHeaders = (...headers) => {
|
|
863
863
|
const mergedHeaders = new Headers();
|
|
864
864
|
for (const header of headers) {
|
|
865
865
|
if (!header) {
|
|
866
866
|
continue;
|
|
867
867
|
}
|
|
868
|
-
const iterator = header instanceof Headers ? headersEntries
|
|
868
|
+
const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);
|
|
869
869
|
for (const [key, value] of iterator) {
|
|
870
870
|
if (value === null) {
|
|
871
871
|
mergedHeaders.delete(key);
|
|
@@ -883,7 +883,7 @@ const mergeHeaders$1 = (...headers) => {
|
|
|
883
883
|
}
|
|
884
884
|
return mergedHeaders;
|
|
885
885
|
};
|
|
886
|
-
|
|
886
|
+
class Interceptors {
|
|
887
887
|
fns = [];
|
|
888
888
|
clear() {
|
|
889
889
|
this.fns = [];
|
|
@@ -916,13 +916,13 @@ let Interceptors$1 = class Interceptors {
|
|
|
916
916
|
this.fns.push(fn);
|
|
917
917
|
return this.fns.length - 1;
|
|
918
918
|
}
|
|
919
|
-
}
|
|
920
|
-
const createInterceptors
|
|
921
|
-
error: new Interceptors
|
|
922
|
-
request: new Interceptors
|
|
923
|
-
response: new Interceptors
|
|
919
|
+
}
|
|
920
|
+
const createInterceptors = () => ({
|
|
921
|
+
error: new Interceptors(),
|
|
922
|
+
request: new Interceptors(),
|
|
923
|
+
response: new Interceptors()
|
|
924
924
|
});
|
|
925
|
-
const defaultQuerySerializer
|
|
925
|
+
const defaultQuerySerializer = createQuerySerializer({
|
|
926
926
|
allowReserved: false,
|
|
927
927
|
array: {
|
|
928
928
|
explode: true,
|
|
@@ -933,34 +933,34 @@ const defaultQuerySerializer$1 = createQuerySerializer$1({
|
|
|
933
933
|
style: "deepObject"
|
|
934
934
|
}
|
|
935
935
|
});
|
|
936
|
-
const defaultHeaders
|
|
936
|
+
const defaultHeaders = {
|
|
937
937
|
"Content-Type": "application/json"
|
|
938
938
|
};
|
|
939
|
-
const createConfig
|
|
940
|
-
...jsonBodySerializer
|
|
941
|
-
headers: defaultHeaders
|
|
939
|
+
const createConfig = (override = {}) => ({
|
|
940
|
+
...jsonBodySerializer,
|
|
941
|
+
headers: defaultHeaders,
|
|
942
942
|
parseAs: "auto",
|
|
943
|
-
querySerializer: defaultQuerySerializer
|
|
943
|
+
querySerializer: defaultQuerySerializer,
|
|
944
944
|
...override
|
|
945
945
|
});
|
|
946
|
-
const createClient
|
|
947
|
-
let _config = mergeConfigs
|
|
946
|
+
const createClient = (config = {}) => {
|
|
947
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
948
948
|
const getConfig = () => ({ ..._config });
|
|
949
949
|
const setConfig = (config2) => {
|
|
950
|
-
_config = mergeConfigs
|
|
950
|
+
_config = mergeConfigs(_config, config2);
|
|
951
951
|
return getConfig();
|
|
952
952
|
};
|
|
953
|
-
const interceptors = createInterceptors
|
|
953
|
+
const interceptors = createInterceptors();
|
|
954
954
|
const beforeRequest = async (options) => {
|
|
955
955
|
const opts = {
|
|
956
956
|
..._config,
|
|
957
957
|
...options,
|
|
958
958
|
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
|
|
959
|
-
headers: mergeHeaders
|
|
959
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
960
960
|
serializedBody: void 0
|
|
961
961
|
};
|
|
962
962
|
if (opts.security) {
|
|
963
|
-
await setAuthParams
|
|
963
|
+
await setAuthParams({
|
|
964
964
|
...opts,
|
|
965
965
|
security: opts.security
|
|
966
966
|
});
|
|
@@ -974,7 +974,7 @@ const createClient$1 = (config = {}) => {
|
|
|
974
974
|
if (opts.body === void 0 || opts.serializedBody === "") {
|
|
975
975
|
opts.headers.delete("Content-Type");
|
|
976
976
|
}
|
|
977
|
-
const url = buildUrl
|
|
977
|
+
const url = buildUrl(opts);
|
|
978
978
|
return { opts, url };
|
|
979
979
|
};
|
|
980
980
|
const request = async (options) => {
|
|
@@ -982,7 +982,7 @@ const createClient$1 = (config = {}) => {
|
|
|
982
982
|
const requestInit = {
|
|
983
983
|
redirect: "follow",
|
|
984
984
|
...opts,
|
|
985
|
-
body: getValidRequestBody
|
|
985
|
+
body: getValidRequestBody(opts)
|
|
986
986
|
};
|
|
987
987
|
let request2 = new Request(url, requestInit);
|
|
988
988
|
for (const fn of interceptors.request.fns) {
|
|
@@ -1026,7 +1026,7 @@ const createClient$1 = (config = {}) => {
|
|
|
1026
1026
|
response
|
|
1027
1027
|
};
|
|
1028
1028
|
if (response.ok) {
|
|
1029
|
-
const parseAs = (opts.parseAs === "auto" ? getParseAs
|
|
1029
|
+
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
1030
1030
|
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
1031
1031
|
let emptyData;
|
|
1032
1032
|
switch (parseAs) {
|
|
@@ -1104,7 +1104,7 @@ const createClient$1 = (config = {}) => {
|
|
|
1104
1104
|
const makeMethodFn = (method) => (options) => request({ ...options, method });
|
|
1105
1105
|
const makeSseFn = (method) => async (options) => {
|
|
1106
1106
|
const { opts, url } = await beforeRequest(options);
|
|
1107
|
-
return createSseClient
|
|
1107
|
+
return createSseClient({
|
|
1108
1108
|
...opts,
|
|
1109
1109
|
body: opts.body,
|
|
1110
1110
|
headers: opts.headers,
|
|
@@ -1122,7 +1122,7 @@ const createClient$1 = (config = {}) => {
|
|
|
1122
1122
|
});
|
|
1123
1123
|
};
|
|
1124
1124
|
return {
|
|
1125
|
-
buildUrl
|
|
1125
|
+
buildUrl,
|
|
1126
1126
|
connect: makeMethodFn("CONNECT"),
|
|
1127
1127
|
delete: makeMethodFn("DELETE"),
|
|
1128
1128
|
get: makeMethodFn("GET"),
|
|
@@ -1149,8 +1149,8 @@ const createClient$1 = (config = {}) => {
|
|
|
1149
1149
|
trace: makeMethodFn("TRACE")
|
|
1150
1150
|
};
|
|
1151
1151
|
};
|
|
1152
|
-
const client = createClient
|
|
1153
|
-
createConfig
|
|
1152
|
+
const client = createClient(
|
|
1153
|
+
createConfig({ baseUrl: "https://api.themolt.net" })
|
|
1154
1154
|
);
|
|
1155
1155
|
const startLegreffierOnboarding = (options) => (options.client ?? client).post({
|
|
1156
1156
|
url: "/public/legreffier/start",
|
|
@@ -1161,1377 +1161,2353 @@ const startLegreffierOnboarding = (options) => (options.client ?? client).post({
|
|
|
1161
1161
|
}
|
|
1162
1162
|
});
|
|
1163
1163
|
const getLegreffierOnboardingStatus = (options) => (options.client ?? client).get({ url: "/public/legreffier/status/{workflowId}", ...options });
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
const
|
|
1185
|
-
const
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
const
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1164
|
+
class MoltNetError extends Error {
|
|
1165
|
+
code;
|
|
1166
|
+
statusCode;
|
|
1167
|
+
detail;
|
|
1168
|
+
constructor(message, options) {
|
|
1169
|
+
super(message);
|
|
1170
|
+
this.name = "MoltNetError";
|
|
1171
|
+
this.code = options.code;
|
|
1172
|
+
this.statusCode = options.statusCode;
|
|
1173
|
+
this.detail = options.detail;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
function problemToError(problem, statusCode) {
|
|
1177
|
+
return new MoltNetError(problem.title ?? "Request failed", {
|
|
1178
|
+
code: problem.type ?? problem.code ?? "UNKNOWN",
|
|
1179
|
+
statusCode,
|
|
1180
|
+
detail: problem.detail
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
async function writeMcpConfig(mcpConfig, dir2) {
|
|
1184
|
+
const targetDir = dir2 ?? process.cwd();
|
|
1185
|
+
const filePath = join(targetDir, ".mcp.json");
|
|
1186
|
+
let existing = {};
|
|
1187
|
+
try {
|
|
1188
|
+
const content = await readFile(filePath, "utf-8");
|
|
1189
|
+
existing = JSON.parse(content);
|
|
1190
|
+
} catch {
|
|
1191
|
+
}
|
|
1192
|
+
const merged = {
|
|
1193
|
+
...existing,
|
|
1194
|
+
mcpServers: {
|
|
1195
|
+
...existing.mcpServers ?? {},
|
|
1196
|
+
...mcpConfig.mcpServers
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
await writeFile(filePath, JSON.stringify(merged, null, 2) + "\n");
|
|
1200
|
+
return filePath;
|
|
1201
|
+
}
|
|
1202
|
+
function getConfigDir() {
|
|
1203
|
+
return join(homedir(), ".config", "moltnet");
|
|
1204
|
+
}
|
|
1205
|
+
function getConfigPath(configDir) {
|
|
1206
|
+
return join(configDir ?? getConfigDir(), "moltnet.json");
|
|
1207
|
+
}
|
|
1208
|
+
async function readConfig(configDir) {
|
|
1209
|
+
const dir2 = configDir ?? getConfigDir();
|
|
1210
|
+
try {
|
|
1211
|
+
const content = await readFile(join(dir2, "moltnet.json"), "utf-8");
|
|
1212
|
+
return JSON.parse(content);
|
|
1213
|
+
} catch {
|
|
1214
|
+
}
|
|
1215
|
+
try {
|
|
1216
|
+
const content = await readFile(join(dir2, "credentials.json"), "utf-8");
|
|
1217
|
+
console.warn("Warning: credentials.json is deprecated. New writes use moltnet.json. Support will be removed in 3 minor versions.");
|
|
1218
|
+
return JSON.parse(content);
|
|
1219
|
+
} catch {
|
|
1220
|
+
return null;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
async function writeConfig(config, configDir) {
|
|
1224
|
+
const dir2 = configDir ?? getConfigDir();
|
|
1225
|
+
await mkdir(dir2, { recursive: true });
|
|
1226
|
+
const filePath = join(dir2, "moltnet.json");
|
|
1227
|
+
await writeFile(filePath, JSON.stringify(config, null, 2) + "\n", {
|
|
1228
|
+
mode: 384
|
|
1229
|
+
});
|
|
1230
|
+
await chmod(filePath, 384);
|
|
1231
|
+
return filePath;
|
|
1232
|
+
}
|
|
1233
|
+
async function updateConfigSection(section, data, configDir) {
|
|
1234
|
+
const config = await readConfig(configDir);
|
|
1235
|
+
if (!config) {
|
|
1236
|
+
throw new Error("No config found — run `moltnet register` first");
|
|
1237
|
+
}
|
|
1238
|
+
const existing = config[section] ?? {};
|
|
1239
|
+
const updated = { ...existing, ...data };
|
|
1240
|
+
Object.assign(config, { [section]: updated });
|
|
1241
|
+
await writeConfig(config, configDir);
|
|
1242
|
+
}
|
|
1243
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
1244
|
+
function isBytes$1(a) {
|
|
1245
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
1246
|
+
}
|
|
1247
|
+
function anumber(n, title = "") {
|
|
1248
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
1249
|
+
const prefix = title && `"${title}" `;
|
|
1250
|
+
throw new Error(`${prefix}expected integer >= 0, got ${n}`);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
function abytes$1(value, length, title = "") {
|
|
1254
|
+
const bytes = isBytes$1(value);
|
|
1255
|
+
const len = value?.length;
|
|
1256
|
+
const needsLen = length !== void 0;
|
|
1257
|
+
if (!bytes || needsLen && len !== length) {
|
|
1258
|
+
const prefix = title && `"${title}" `;
|
|
1259
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
1260
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
1261
|
+
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
1262
|
+
}
|
|
1263
|
+
return value;
|
|
1264
|
+
}
|
|
1265
|
+
function aexists(instance, checkFinished = true) {
|
|
1266
|
+
if (instance.destroyed)
|
|
1267
|
+
throw new Error("Hash instance has been destroyed");
|
|
1268
|
+
if (checkFinished && instance.finished)
|
|
1269
|
+
throw new Error("Hash#digest() has already been called");
|
|
1270
|
+
}
|
|
1271
|
+
function aoutput(out, instance) {
|
|
1272
|
+
abytes$1(out, void 0, "digestInto() output");
|
|
1273
|
+
const min = instance.outputLen;
|
|
1274
|
+
if (out.length < min) {
|
|
1275
|
+
throw new Error('"digestInto() output" expected to be of length >=' + min);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
function clean(...arrays) {
|
|
1279
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
1280
|
+
arrays[i].fill(0);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
function createView(arr) {
|
|
1284
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
1285
|
+
}
|
|
1286
|
+
const hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
1287
|
+
// @ts-ignore
|
|
1288
|
+
typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
|
|
1289
|
+
))();
|
|
1290
|
+
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
1291
|
+
function bytesToHex$1(bytes) {
|
|
1292
|
+
abytes$1(bytes);
|
|
1293
|
+
if (hasHexBuiltin)
|
|
1294
|
+
return bytes.toHex();
|
|
1295
|
+
let hex = "";
|
|
1296
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1297
|
+
hex += hexes[bytes[i]];
|
|
1298
|
+
}
|
|
1299
|
+
return hex;
|
|
1300
|
+
}
|
|
1301
|
+
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
1302
|
+
function asciiToBase16(ch) {
|
|
1303
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
1304
|
+
return ch - asciis._0;
|
|
1305
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
1306
|
+
return ch - (asciis.A - 10);
|
|
1307
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
1308
|
+
return ch - (asciis.a - 10);
|
|
1196
1309
|
return;
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1310
|
+
}
|
|
1311
|
+
function hexToBytes$1(hex) {
|
|
1312
|
+
if (typeof hex !== "string")
|
|
1313
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
1314
|
+
if (hasHexBuiltin)
|
|
1315
|
+
return Uint8Array.fromHex(hex);
|
|
1202
1316
|
const hl = hex.length;
|
|
1203
1317
|
const al = hl / 2;
|
|
1204
1318
|
if (hl % 2)
|
|
1205
|
-
|
|
1206
|
-
const array =
|
|
1319
|
+
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
1320
|
+
const array = new Uint8Array(al);
|
|
1207
1321
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
1208
|
-
const n1 =
|
|
1209
|
-
const n2 =
|
|
1210
|
-
if (n1 === void 0 || n2 === void 0)
|
|
1211
|
-
|
|
1322
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
1323
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
1324
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
1325
|
+
const char = hex[hi] + hex[hi + 1];
|
|
1326
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
1327
|
+
}
|
|
1212
1328
|
array[ai] = n1 * 16 + n2;
|
|
1213
1329
|
}
|
|
1214
1330
|
return array;
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1331
|
+
}
|
|
1332
|
+
function concatBytes$1(...arrays) {
|
|
1333
|
+
let sum = 0;
|
|
1334
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
1335
|
+
const a = arrays[i];
|
|
1336
|
+
abytes$1(a);
|
|
1337
|
+
sum += a.length;
|
|
1338
|
+
}
|
|
1339
|
+
const res = new Uint8Array(sum);
|
|
1340
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
1341
|
+
const a = arrays[i];
|
|
1342
|
+
res.set(a, pad);
|
|
1224
1343
|
pad += a.length;
|
|
1225
|
-
});
|
|
1226
|
-
return r;
|
|
1227
|
-
};
|
|
1228
|
-
const randomBytes = (len = L) => {
|
|
1229
|
-
const c = cr();
|
|
1230
|
-
return c.getRandomValues(u8n(len));
|
|
1231
|
-
};
|
|
1232
|
-
const big = BigInt;
|
|
1233
|
-
const arange = (n, min, max, msg = "bad number: out of range") => isBig(n) && min <= n && n < max ? n : err(msg);
|
|
1234
|
-
const M = (a, b = P) => {
|
|
1235
|
-
const r = a % b;
|
|
1236
|
-
return r >= 0n ? r : b + r;
|
|
1237
|
-
};
|
|
1238
|
-
const modN = (a) => M(a, N);
|
|
1239
|
-
const invert = (num, md) => {
|
|
1240
|
-
if (num === 0n || md <= 0n)
|
|
1241
|
-
err("no inverse n=" + num + " mod=" + md);
|
|
1242
|
-
let a = M(num, md), b = md, x = 0n, u = 1n;
|
|
1243
|
-
while (a !== 0n) {
|
|
1244
|
-
const q = b / a, r = b % a;
|
|
1245
|
-
const m = x - u * q;
|
|
1246
|
-
b = a, a = r, x = u, u = m;
|
|
1247
1344
|
}
|
|
1248
|
-
return
|
|
1249
|
-
}
|
|
1250
|
-
|
|
1251
|
-
const
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1345
|
+
return res;
|
|
1346
|
+
}
|
|
1347
|
+
function createHasher(hashCons, info = {}) {
|
|
1348
|
+
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
1349
|
+
const tmp = hashCons(void 0);
|
|
1350
|
+
hashC.outputLen = tmp.outputLen;
|
|
1351
|
+
hashC.blockLen = tmp.blockLen;
|
|
1352
|
+
hashC.create = (opts) => hashCons(opts);
|
|
1353
|
+
Object.assign(hashC, info);
|
|
1354
|
+
return Object.freeze(hashC);
|
|
1355
|
+
}
|
|
1356
|
+
function randomBytes$1(bytesLength = 32) {
|
|
1357
|
+
const cr2 = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
1358
|
+
if (typeof cr2?.getRandomValues !== "function")
|
|
1359
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
1360
|
+
return cr2.getRandomValues(new Uint8Array(bytesLength));
|
|
1361
|
+
}
|
|
1362
|
+
const oidNist = (suffix) => ({
|
|
1363
|
+
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
1364
|
+
});
|
|
1365
|
+
class HashMD {
|
|
1366
|
+
blockLen;
|
|
1367
|
+
outputLen;
|
|
1368
|
+
padOffset;
|
|
1369
|
+
isLE;
|
|
1370
|
+
// For partial updates less than block size
|
|
1371
|
+
buffer;
|
|
1372
|
+
view;
|
|
1373
|
+
finished = false;
|
|
1374
|
+
length = 0;
|
|
1375
|
+
pos = 0;
|
|
1376
|
+
destroyed = false;
|
|
1377
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
1378
|
+
this.blockLen = blockLen;
|
|
1379
|
+
this.outputLen = outputLen;
|
|
1380
|
+
this.padOffset = padOffset;
|
|
1381
|
+
this.isLE = isLE;
|
|
1382
|
+
this.buffer = new Uint8Array(blockLen);
|
|
1383
|
+
this.view = createView(this.buffer);
|
|
1384
|
+
}
|
|
1385
|
+
update(data) {
|
|
1386
|
+
aexists(this);
|
|
1387
|
+
abytes$1(data);
|
|
1388
|
+
const { view, buffer, blockLen } = this;
|
|
1389
|
+
const len = data.length;
|
|
1390
|
+
for (let pos = 0; pos < len; ) {
|
|
1391
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
1392
|
+
if (take === blockLen) {
|
|
1393
|
+
const dataView = createView(data);
|
|
1394
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
1395
|
+
this.process(dataView, pos);
|
|
1396
|
+
continue;
|
|
1397
|
+
}
|
|
1398
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
1399
|
+
this.pos += take;
|
|
1400
|
+
pos += take;
|
|
1401
|
+
if (this.pos === blockLen) {
|
|
1402
|
+
this.process(view, 0);
|
|
1403
|
+
this.pos = 0;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
this.length += data.length;
|
|
1407
|
+
this.roundClean();
|
|
1408
|
+
return this;
|
|
1272
1409
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1410
|
+
digestInto(out) {
|
|
1411
|
+
aexists(this);
|
|
1412
|
+
aoutput(out, this);
|
|
1413
|
+
this.finished = true;
|
|
1414
|
+
const { buffer, view, blockLen, isLE } = this;
|
|
1415
|
+
let { pos } = this;
|
|
1416
|
+
buffer[pos++] = 128;
|
|
1417
|
+
clean(this.buffer.subarray(pos));
|
|
1418
|
+
if (this.padOffset > blockLen - pos) {
|
|
1419
|
+
this.process(view, 0);
|
|
1420
|
+
pos = 0;
|
|
1421
|
+
}
|
|
1422
|
+
for (let i = pos; i < blockLen; i++)
|
|
1423
|
+
buffer[i] = 0;
|
|
1424
|
+
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
1425
|
+
this.process(view, 0);
|
|
1426
|
+
const oview = createView(out);
|
|
1427
|
+
const len = this.outputLen;
|
|
1428
|
+
if (len % 4)
|
|
1429
|
+
throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
1430
|
+
const outLen = len / 4;
|
|
1431
|
+
const state = this.get();
|
|
1432
|
+
if (outLen > state.length)
|
|
1433
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
1434
|
+
for (let i = 0; i < outLen; i++)
|
|
1435
|
+
oview.setUint32(4 * i, state[i], isLE);
|
|
1436
|
+
}
|
|
1437
|
+
digest() {
|
|
1438
|
+
const { buffer, outputLen } = this;
|
|
1439
|
+
this.digestInto(buffer);
|
|
1440
|
+
const res = buffer.slice(0, outputLen);
|
|
1441
|
+
this.destroy();
|
|
1442
|
+
return res;
|
|
1443
|
+
}
|
|
1444
|
+
_cloneInto(to) {
|
|
1445
|
+
to ||= new this.constructor();
|
|
1446
|
+
to.set(...this.get());
|
|
1447
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
1448
|
+
to.destroyed = destroyed;
|
|
1449
|
+
to.finished = finished;
|
|
1450
|
+
to.length = length;
|
|
1451
|
+
to.pos = pos;
|
|
1452
|
+
if (length % blockLen)
|
|
1453
|
+
to.buffer.set(buffer);
|
|
1454
|
+
return to;
|
|
1455
|
+
}
|
|
1456
|
+
clone() {
|
|
1457
|
+
return this._cloneInto();
|
|
1275
1458
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1459
|
+
}
|
|
1460
|
+
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
1461
|
+
1779033703,
|
|
1462
|
+
4089235720,
|
|
1463
|
+
3144134277,
|
|
1464
|
+
2227873595,
|
|
1465
|
+
1013904242,
|
|
1466
|
+
4271175723,
|
|
1467
|
+
2773480762,
|
|
1468
|
+
1595750129,
|
|
1469
|
+
1359893119,
|
|
1470
|
+
2917565137,
|
|
1471
|
+
2600822924,
|
|
1472
|
+
725511199,
|
|
1473
|
+
528734635,
|
|
1474
|
+
4215389547,
|
|
1475
|
+
1541459225,
|
|
1476
|
+
327033209
|
|
1477
|
+
]);
|
|
1478
|
+
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
1479
|
+
const _32n = /* @__PURE__ */ BigInt(32);
|
|
1480
|
+
function fromBig(n, le = false) {
|
|
1481
|
+
if (le)
|
|
1482
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
1483
|
+
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
1484
|
+
}
|
|
1485
|
+
function split(lst, le = false) {
|
|
1486
|
+
const len = lst.length;
|
|
1487
|
+
let Ah = new Uint32Array(len);
|
|
1488
|
+
let Al = new Uint32Array(len);
|
|
1489
|
+
for (let i = 0; i < len; i++) {
|
|
1490
|
+
const { h: h2, l } = fromBig(lst[i], le);
|
|
1491
|
+
[Ah[i], Al[i]] = [h2, l];
|
|
1492
|
+
}
|
|
1493
|
+
return [Ah, Al];
|
|
1494
|
+
}
|
|
1495
|
+
const shrSH = (h2, _l, s) => h2 >>> s;
|
|
1496
|
+
const shrSL = (h2, l, s) => h2 << 32 - s | l >>> s;
|
|
1497
|
+
const rotrSH = (h2, l, s) => h2 >>> s | l << 32 - s;
|
|
1498
|
+
const rotrSL = (h2, l, s) => h2 << 32 - s | l >>> s;
|
|
1499
|
+
const rotrBH = (h2, l, s) => h2 << 64 - s | l >>> s - 32;
|
|
1500
|
+
const rotrBL = (h2, l, s) => h2 >>> s - 32 | l << 64 - s;
|
|
1501
|
+
function add(Ah, Al, Bh, Bl) {
|
|
1502
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
1503
|
+
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
1504
|
+
}
|
|
1505
|
+
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
1506
|
+
const add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
1507
|
+
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
1508
|
+
const add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
1509
|
+
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
1510
|
+
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
1511
|
+
const K512 = /* @__PURE__ */ (() => split([
|
|
1512
|
+
"0x428a2f98d728ae22",
|
|
1513
|
+
"0x7137449123ef65cd",
|
|
1514
|
+
"0xb5c0fbcfec4d3b2f",
|
|
1515
|
+
"0xe9b5dba58189dbbc",
|
|
1516
|
+
"0x3956c25bf348b538",
|
|
1517
|
+
"0x59f111f1b605d019",
|
|
1518
|
+
"0x923f82a4af194f9b",
|
|
1519
|
+
"0xab1c5ed5da6d8118",
|
|
1520
|
+
"0xd807aa98a3030242",
|
|
1521
|
+
"0x12835b0145706fbe",
|
|
1522
|
+
"0x243185be4ee4b28c",
|
|
1523
|
+
"0x550c7dc3d5ffb4e2",
|
|
1524
|
+
"0x72be5d74f27b896f",
|
|
1525
|
+
"0x80deb1fe3b1696b1",
|
|
1526
|
+
"0x9bdc06a725c71235",
|
|
1527
|
+
"0xc19bf174cf692694",
|
|
1528
|
+
"0xe49b69c19ef14ad2",
|
|
1529
|
+
"0xefbe4786384f25e3",
|
|
1530
|
+
"0x0fc19dc68b8cd5b5",
|
|
1531
|
+
"0x240ca1cc77ac9c65",
|
|
1532
|
+
"0x2de92c6f592b0275",
|
|
1533
|
+
"0x4a7484aa6ea6e483",
|
|
1534
|
+
"0x5cb0a9dcbd41fbd4",
|
|
1535
|
+
"0x76f988da831153b5",
|
|
1536
|
+
"0x983e5152ee66dfab",
|
|
1537
|
+
"0xa831c66d2db43210",
|
|
1538
|
+
"0xb00327c898fb213f",
|
|
1539
|
+
"0xbf597fc7beef0ee4",
|
|
1540
|
+
"0xc6e00bf33da88fc2",
|
|
1541
|
+
"0xd5a79147930aa725",
|
|
1542
|
+
"0x06ca6351e003826f",
|
|
1543
|
+
"0x142929670a0e6e70",
|
|
1544
|
+
"0x27b70a8546d22ffc",
|
|
1545
|
+
"0x2e1b21385c26c926",
|
|
1546
|
+
"0x4d2c6dfc5ac42aed",
|
|
1547
|
+
"0x53380d139d95b3df",
|
|
1548
|
+
"0x650a73548baf63de",
|
|
1549
|
+
"0x766a0abb3c77b2a8",
|
|
1550
|
+
"0x81c2c92e47edaee6",
|
|
1551
|
+
"0x92722c851482353b",
|
|
1552
|
+
"0xa2bfe8a14cf10364",
|
|
1553
|
+
"0xa81a664bbc423001",
|
|
1554
|
+
"0xc24b8b70d0f89791",
|
|
1555
|
+
"0xc76c51a30654be30",
|
|
1556
|
+
"0xd192e819d6ef5218",
|
|
1557
|
+
"0xd69906245565a910",
|
|
1558
|
+
"0xf40e35855771202a",
|
|
1559
|
+
"0x106aa07032bbd1b8",
|
|
1560
|
+
"0x19a4c116b8d2d0c8",
|
|
1561
|
+
"0x1e376c085141ab53",
|
|
1562
|
+
"0x2748774cdf8eeb99",
|
|
1563
|
+
"0x34b0bcb5e19b48a8",
|
|
1564
|
+
"0x391c0cb3c5c95a63",
|
|
1565
|
+
"0x4ed8aa4ae3418acb",
|
|
1566
|
+
"0x5b9cca4f7763e373",
|
|
1567
|
+
"0x682e6ff3d6b2b8a3",
|
|
1568
|
+
"0x748f82ee5defb2fc",
|
|
1569
|
+
"0x78a5636f43172f60",
|
|
1570
|
+
"0x84c87814a1f0ab72",
|
|
1571
|
+
"0x8cc702081a6439ec",
|
|
1572
|
+
"0x90befffa23631e28",
|
|
1573
|
+
"0xa4506cebde82bde9",
|
|
1574
|
+
"0xbef9a3f7b2c67915",
|
|
1575
|
+
"0xc67178f2e372532b",
|
|
1576
|
+
"0xca273eceea26619c",
|
|
1577
|
+
"0xd186b8c721c0c207",
|
|
1578
|
+
"0xeada7dd6cde0eb1e",
|
|
1579
|
+
"0xf57d4f7fee6ed178",
|
|
1580
|
+
"0x06f067aa72176fba",
|
|
1581
|
+
"0x0a637dc5a2c898a6",
|
|
1582
|
+
"0x113f9804bef90dae",
|
|
1583
|
+
"0x1b710b35131c471b",
|
|
1584
|
+
"0x28db77f523047d84",
|
|
1585
|
+
"0x32caab7b40c72493",
|
|
1586
|
+
"0x3c9ebe0a15c9bebc",
|
|
1587
|
+
"0x431d67c49c100d4c",
|
|
1588
|
+
"0x4cc5d4becb3e42b6",
|
|
1589
|
+
"0x597f299cfc657e2a",
|
|
1590
|
+
"0x5fcb6fab3ad6faec",
|
|
1591
|
+
"0x6c44198c4a475817"
|
|
1592
|
+
].map((n) => BigInt(n))))();
|
|
1593
|
+
const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
|
1594
|
+
const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
1595
|
+
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
1596
|
+
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
1597
|
+
class SHA2_64B extends HashMD {
|
|
1598
|
+
constructor(outputLen) {
|
|
1599
|
+
super(128, outputLen, 16, false);
|
|
1600
|
+
}
|
|
1601
|
+
// prettier-ignore
|
|
1602
|
+
get() {
|
|
1603
|
+
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
1604
|
+
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
|
1605
|
+
}
|
|
1606
|
+
// prettier-ignore
|
|
1607
|
+
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
|
1608
|
+
this.Ah = Ah | 0;
|
|
1609
|
+
this.Al = Al | 0;
|
|
1610
|
+
this.Bh = Bh | 0;
|
|
1611
|
+
this.Bl = Bl | 0;
|
|
1612
|
+
this.Ch = Ch | 0;
|
|
1613
|
+
this.Cl = Cl | 0;
|
|
1614
|
+
this.Dh = Dh | 0;
|
|
1615
|
+
this.Dl = Dl | 0;
|
|
1616
|
+
this.Eh = Eh | 0;
|
|
1617
|
+
this.El = El | 0;
|
|
1618
|
+
this.Fh = Fh | 0;
|
|
1619
|
+
this.Fl = Fl | 0;
|
|
1620
|
+
this.Gh = Gh | 0;
|
|
1621
|
+
this.Gl = Gl | 0;
|
|
1622
|
+
this.Hh = Hh | 0;
|
|
1623
|
+
this.Hl = Hl | 0;
|
|
1624
|
+
}
|
|
1625
|
+
process(view, offset) {
|
|
1626
|
+
for (let i = 0; i < 16; i++, offset += 4) {
|
|
1627
|
+
SHA512_W_H[i] = view.getUint32(offset);
|
|
1628
|
+
SHA512_W_L[i] = view.getUint32(offset += 4);
|
|
1629
|
+
}
|
|
1630
|
+
for (let i = 16; i < 80; i++) {
|
|
1631
|
+
const W15h = SHA512_W_H[i - 15] | 0;
|
|
1632
|
+
const W15l = SHA512_W_L[i - 15] | 0;
|
|
1633
|
+
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
1634
|
+
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
1635
|
+
const W2h = SHA512_W_H[i - 2] | 0;
|
|
1636
|
+
const W2l = SHA512_W_L[i - 2] | 0;
|
|
1637
|
+
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
1638
|
+
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
1639
|
+
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
1640
|
+
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
|
1641
|
+
SHA512_W_H[i] = SUMh | 0;
|
|
1642
|
+
SHA512_W_L[i] = SUMl | 0;
|
|
1643
|
+
}
|
|
1644
|
+
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
1645
|
+
for (let i = 0; i < 80; i++) {
|
|
1646
|
+
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
1647
|
+
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
1648
|
+
const CHIh = Eh & Fh ^ ~Eh & Gh;
|
|
1649
|
+
const CHIl = El & Fl ^ ~El & Gl;
|
|
1650
|
+
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
1651
|
+
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
1652
|
+
const T1l = T1ll | 0;
|
|
1653
|
+
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
1654
|
+
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
1655
|
+
const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
|
|
1656
|
+
const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
|
|
1657
|
+
Hh = Gh | 0;
|
|
1658
|
+
Hl = Gl | 0;
|
|
1659
|
+
Gh = Fh | 0;
|
|
1660
|
+
Gl = Fl | 0;
|
|
1661
|
+
Fh = Eh | 0;
|
|
1662
|
+
Fl = El | 0;
|
|
1663
|
+
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
1664
|
+
Dh = Ch | 0;
|
|
1665
|
+
Dl = Cl | 0;
|
|
1666
|
+
Ch = Bh | 0;
|
|
1667
|
+
Cl = Bl | 0;
|
|
1668
|
+
Bh = Ah | 0;
|
|
1669
|
+
Bl = Al | 0;
|
|
1670
|
+
const All = add3L(T1l, sigma0l, MAJl);
|
|
1671
|
+
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
1672
|
+
Al = All | 0;
|
|
1673
|
+
}
|
|
1674
|
+
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
1675
|
+
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
1676
|
+
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
1677
|
+
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
1678
|
+
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
1679
|
+
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
1680
|
+
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
1681
|
+
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
1682
|
+
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
1683
|
+
}
|
|
1684
|
+
roundClean() {
|
|
1685
|
+
clean(SHA512_W_H, SHA512_W_L);
|
|
1686
|
+
}
|
|
1687
|
+
destroy() {
|
|
1688
|
+
clean(this.buffer);
|
|
1689
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
1298
1690
|
}
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
throw new Error("bad point: equation left != right (2)");
|
|
1320
|
-
return this;
|
|
1691
|
+
}
|
|
1692
|
+
class _SHA512 extends SHA2_64B {
|
|
1693
|
+
Ah = SHA512_IV[0] | 0;
|
|
1694
|
+
Al = SHA512_IV[1] | 0;
|
|
1695
|
+
Bh = SHA512_IV[2] | 0;
|
|
1696
|
+
Bl = SHA512_IV[3] | 0;
|
|
1697
|
+
Ch = SHA512_IV[4] | 0;
|
|
1698
|
+
Cl = SHA512_IV[5] | 0;
|
|
1699
|
+
Dh = SHA512_IV[6] | 0;
|
|
1700
|
+
Dl = SHA512_IV[7] | 0;
|
|
1701
|
+
Eh = SHA512_IV[8] | 0;
|
|
1702
|
+
El = SHA512_IV[9] | 0;
|
|
1703
|
+
Fh = SHA512_IV[10] | 0;
|
|
1704
|
+
Fl = SHA512_IV[11] | 0;
|
|
1705
|
+
Gh = SHA512_IV[12] | 0;
|
|
1706
|
+
Gl = SHA512_IV[13] | 0;
|
|
1707
|
+
Hh = SHA512_IV[14] | 0;
|
|
1708
|
+
Hl = SHA512_IV[15] | 0;
|
|
1709
|
+
constructor() {
|
|
1710
|
+
super(64);
|
|
1321
1711
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1712
|
+
}
|
|
1713
|
+
const sha512 = /* @__PURE__ */ createHasher(
|
|
1714
|
+
() => new _SHA512(),
|
|
1715
|
+
/* @__PURE__ */ oidNist(3)
|
|
1716
|
+
);
|
|
1717
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
1718
|
+
const _0n$3 = /* @__PURE__ */ BigInt(0);
|
|
1719
|
+
const _1n$4 = /* @__PURE__ */ BigInt(1);
|
|
1720
|
+
function abool(value, title = "") {
|
|
1721
|
+
if (typeof value !== "boolean") {
|
|
1722
|
+
const prefix = title && `"${title}" `;
|
|
1723
|
+
throw new Error(prefix + "expected boolean, got type=" + typeof value);
|
|
1724
|
+
}
|
|
1725
|
+
return value;
|
|
1726
|
+
}
|
|
1727
|
+
function abignumber(n) {
|
|
1728
|
+
if (typeof n === "bigint") {
|
|
1729
|
+
if (!isPosBig(n))
|
|
1730
|
+
throw new Error("positive bigint expected, got " + n);
|
|
1731
|
+
} else
|
|
1732
|
+
anumber(n);
|
|
1733
|
+
return n;
|
|
1734
|
+
}
|
|
1735
|
+
function hexToNumber(hex) {
|
|
1736
|
+
if (typeof hex !== "string")
|
|
1737
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
1738
|
+
return hex === "" ? _0n$3 : BigInt("0x" + hex);
|
|
1739
|
+
}
|
|
1740
|
+
function bytesToNumberBE(bytes) {
|
|
1741
|
+
return hexToNumber(bytesToHex$1(bytes));
|
|
1742
|
+
}
|
|
1743
|
+
function bytesToNumberLE(bytes) {
|
|
1744
|
+
return hexToNumber(bytesToHex$1(copyBytes(abytes$1(bytes)).reverse()));
|
|
1745
|
+
}
|
|
1746
|
+
function numberToBytesBE(n, len) {
|
|
1747
|
+
anumber(len);
|
|
1748
|
+
n = abignumber(n);
|
|
1749
|
+
const res = hexToBytes$1(n.toString(16).padStart(len * 2, "0"));
|
|
1750
|
+
if (res.length !== len)
|
|
1751
|
+
throw new Error("number too large");
|
|
1752
|
+
return res;
|
|
1753
|
+
}
|
|
1754
|
+
function numberToBytesLE(n, len) {
|
|
1755
|
+
return numberToBytesBE(n, len).reverse();
|
|
1756
|
+
}
|
|
1757
|
+
function copyBytes(bytes) {
|
|
1758
|
+
return Uint8Array.from(bytes);
|
|
1759
|
+
}
|
|
1760
|
+
const isPosBig = (n) => typeof n === "bigint" && _0n$3 <= n;
|
|
1761
|
+
function inRange(n, min, max) {
|
|
1762
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
1763
|
+
}
|
|
1764
|
+
function aInRange(title, n, min, max) {
|
|
1765
|
+
if (!inRange(n, min, max))
|
|
1766
|
+
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
1767
|
+
}
|
|
1768
|
+
const bitMask = (n) => (_1n$4 << BigInt(n)) - _1n$4;
|
|
1769
|
+
function validateObject(object, fields = {}, optFields = {}) {
|
|
1770
|
+
if (!object || typeof object !== "object")
|
|
1771
|
+
throw new Error("expected valid options object");
|
|
1772
|
+
function checkField(fieldName, expectedType, isOpt) {
|
|
1773
|
+
const val = object[fieldName];
|
|
1774
|
+
if (isOpt && val === void 0)
|
|
1775
|
+
return;
|
|
1776
|
+
const current = typeof val;
|
|
1777
|
+
if (current !== expectedType || val === null)
|
|
1778
|
+
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
1779
|
+
}
|
|
1780
|
+
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
|
|
1781
|
+
iter(fields, false);
|
|
1782
|
+
iter(optFields, true);
|
|
1783
|
+
}
|
|
1784
|
+
function memoized(fn) {
|
|
1785
|
+
const map = /* @__PURE__ */ new WeakMap();
|
|
1786
|
+
return (arg, ...args) => {
|
|
1787
|
+
const val = map.get(arg);
|
|
1788
|
+
if (val !== void 0)
|
|
1789
|
+
return val;
|
|
1790
|
+
const computed = fn(arg, ...args);
|
|
1791
|
+
map.set(arg, computed);
|
|
1792
|
+
return computed;
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
1796
|
+
const _0n$2 = /* @__PURE__ */ BigInt(0), _1n$3 = /* @__PURE__ */ BigInt(1), _2n$2 = /* @__PURE__ */ BigInt(2);
|
|
1797
|
+
const _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5);
|
|
1798
|
+
const _7n = /* @__PURE__ */ BigInt(7), _8n$2 = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9);
|
|
1799
|
+
const _16n = /* @__PURE__ */ BigInt(16);
|
|
1800
|
+
function mod(a, b) {
|
|
1801
|
+
const result = a % b;
|
|
1802
|
+
return result >= _0n$2 ? result : b + result;
|
|
1803
|
+
}
|
|
1804
|
+
function pow2$1(x, power, modulo) {
|
|
1805
|
+
let res = x;
|
|
1806
|
+
while (power-- > _0n$2) {
|
|
1807
|
+
res *= res;
|
|
1808
|
+
res %= modulo;
|
|
1331
1809
|
}
|
|
1332
|
-
|
|
1333
|
-
|
|
1810
|
+
return res;
|
|
1811
|
+
}
|
|
1812
|
+
function invert$1(number, modulo) {
|
|
1813
|
+
if (number === _0n$2)
|
|
1814
|
+
throw new Error("invert: expected non-zero number");
|
|
1815
|
+
if (modulo <= _0n$2)
|
|
1816
|
+
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
1817
|
+
let a = mod(number, modulo);
|
|
1818
|
+
let b = modulo;
|
|
1819
|
+
let x = _0n$2, u = _1n$3;
|
|
1820
|
+
while (a !== _0n$2) {
|
|
1821
|
+
const q = b / a;
|
|
1822
|
+
const r = b % a;
|
|
1823
|
+
const m = x - u * q;
|
|
1824
|
+
b = a, a = r, x = u, u = m;
|
|
1334
1825
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1826
|
+
const gcd = b;
|
|
1827
|
+
if (gcd !== _1n$3)
|
|
1828
|
+
throw new Error("invert: does not exist");
|
|
1829
|
+
return mod(x, modulo);
|
|
1830
|
+
}
|
|
1831
|
+
function assertIsSquare(Fp, root, n) {
|
|
1832
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
1833
|
+
throw new Error("Cannot find square root");
|
|
1834
|
+
}
|
|
1835
|
+
function sqrt3mod4(Fp, n) {
|
|
1836
|
+
const p1div4 = (Fp.ORDER + _1n$3) / _4n;
|
|
1837
|
+
const root = Fp.pow(n, p1div4);
|
|
1838
|
+
assertIsSquare(Fp, root, n);
|
|
1839
|
+
return root;
|
|
1840
|
+
}
|
|
1841
|
+
function sqrt5mod8(Fp, n) {
|
|
1842
|
+
const p5div8 = (Fp.ORDER - _5n$1) / _8n$2;
|
|
1843
|
+
const n2 = Fp.mul(n, _2n$2);
|
|
1844
|
+
const v = Fp.pow(n2, p5div8);
|
|
1845
|
+
const nv = Fp.mul(n, v);
|
|
1846
|
+
const i = Fp.mul(Fp.mul(nv, _2n$2), v);
|
|
1847
|
+
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
1848
|
+
assertIsSquare(Fp, root, n);
|
|
1849
|
+
return root;
|
|
1850
|
+
}
|
|
1851
|
+
function sqrt9mod16(P2) {
|
|
1852
|
+
const Fp_ = Field(P2);
|
|
1853
|
+
const tn = tonelliShanks(P2);
|
|
1854
|
+
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
1855
|
+
const c2 = tn(Fp_, c1);
|
|
1856
|
+
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
1857
|
+
const c4 = (P2 + _7n) / _16n;
|
|
1858
|
+
return (Fp, n) => {
|
|
1859
|
+
let tv1 = Fp.pow(n, c4);
|
|
1860
|
+
let tv2 = Fp.mul(tv1, c1);
|
|
1861
|
+
const tv3 = Fp.mul(tv1, c2);
|
|
1862
|
+
const tv4 = Fp.mul(tv1, c3);
|
|
1863
|
+
const e1 = Fp.eql(Fp.sqr(tv2), n);
|
|
1864
|
+
const e2 = Fp.eql(Fp.sqr(tv3), n);
|
|
1865
|
+
tv1 = Fp.cmov(tv1, tv2, e1);
|
|
1866
|
+
tv2 = Fp.cmov(tv4, tv3, e2);
|
|
1867
|
+
const e3 = Fp.eql(Fp.sqr(tv2), n);
|
|
1868
|
+
const root = Fp.cmov(tv1, tv2, e3);
|
|
1869
|
+
assertIsSquare(Fp, root, n);
|
|
1870
|
+
return root;
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
function tonelliShanks(P2) {
|
|
1874
|
+
if (P2 < _3n)
|
|
1875
|
+
throw new Error("sqrt is not defined for small field");
|
|
1876
|
+
let Q = P2 - _1n$3;
|
|
1877
|
+
let S = 0;
|
|
1878
|
+
while (Q % _2n$2 === _0n$2) {
|
|
1879
|
+
Q /= _2n$2;
|
|
1880
|
+
S++;
|
|
1881
|
+
}
|
|
1882
|
+
let Z = _2n$2;
|
|
1883
|
+
const _Fp = Field(P2);
|
|
1884
|
+
while (FpLegendre(_Fp, Z) === 1) {
|
|
1885
|
+
if (Z++ > 1e3)
|
|
1886
|
+
throw new Error("Cannot find square root: probably non-prime P");
|
|
1887
|
+
}
|
|
1888
|
+
if (S === 1)
|
|
1889
|
+
return sqrt3mod4;
|
|
1890
|
+
let cc = _Fp.pow(Z, Q);
|
|
1891
|
+
const Q1div2 = (Q + _1n$3) / _2n$2;
|
|
1892
|
+
return function tonelliSlow(Fp, n) {
|
|
1893
|
+
if (Fp.is0(n))
|
|
1894
|
+
return n;
|
|
1895
|
+
if (FpLegendre(Fp, n) !== 1)
|
|
1896
|
+
throw new Error("Cannot find square root");
|
|
1897
|
+
let M2 = S;
|
|
1898
|
+
let c = Fp.mul(Fp.ONE, cc);
|
|
1899
|
+
let t = Fp.pow(n, Q);
|
|
1900
|
+
let R = Fp.pow(n, Q1div2);
|
|
1901
|
+
while (!Fp.eql(t, Fp.ONE)) {
|
|
1902
|
+
if (Fp.is0(t))
|
|
1903
|
+
return Fp.ZERO;
|
|
1904
|
+
let i = 1;
|
|
1905
|
+
let t_tmp = Fp.sqr(t);
|
|
1906
|
+
while (!Fp.eql(t_tmp, Fp.ONE)) {
|
|
1907
|
+
i++;
|
|
1908
|
+
t_tmp = Fp.sqr(t_tmp);
|
|
1909
|
+
if (i === M2)
|
|
1910
|
+
throw new Error("Cannot find square root");
|
|
1911
|
+
}
|
|
1912
|
+
const exponent = _1n$3 << BigInt(M2 - i - 1);
|
|
1913
|
+
const b = Fp.pow(c, exponent);
|
|
1914
|
+
M2 = i;
|
|
1915
|
+
c = Fp.sqr(b);
|
|
1916
|
+
t = Fp.mul(t, c);
|
|
1917
|
+
R = Fp.mul(R, b);
|
|
1918
|
+
}
|
|
1919
|
+
return R;
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
function FpSqrt(P2) {
|
|
1923
|
+
if (P2 % _4n === _3n)
|
|
1924
|
+
return sqrt3mod4;
|
|
1925
|
+
if (P2 % _8n$2 === _5n$1)
|
|
1926
|
+
return sqrt5mod8;
|
|
1927
|
+
if (P2 % _16n === _9n)
|
|
1928
|
+
return sqrt9mod16(P2);
|
|
1929
|
+
return tonelliShanks(P2);
|
|
1930
|
+
}
|
|
1931
|
+
const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n$3) === _1n$3;
|
|
1932
|
+
const FIELD_FIELDS = [
|
|
1933
|
+
"create",
|
|
1934
|
+
"isValid",
|
|
1935
|
+
"is0",
|
|
1936
|
+
"neg",
|
|
1937
|
+
"inv",
|
|
1938
|
+
"sqrt",
|
|
1939
|
+
"sqr",
|
|
1940
|
+
"eql",
|
|
1941
|
+
"add",
|
|
1942
|
+
"sub",
|
|
1943
|
+
"mul",
|
|
1944
|
+
"pow",
|
|
1945
|
+
"div",
|
|
1946
|
+
"addN",
|
|
1947
|
+
"subN",
|
|
1948
|
+
"mulN",
|
|
1949
|
+
"sqrN"
|
|
1950
|
+
];
|
|
1951
|
+
function validateField(field) {
|
|
1952
|
+
const initial = {
|
|
1953
|
+
ORDER: "bigint",
|
|
1954
|
+
BYTES: "number",
|
|
1955
|
+
BITS: "number"
|
|
1956
|
+
};
|
|
1957
|
+
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
1958
|
+
map[val] = "function";
|
|
1959
|
+
return map;
|
|
1960
|
+
}, initial);
|
|
1961
|
+
validateObject(field, opts);
|
|
1962
|
+
return field;
|
|
1963
|
+
}
|
|
1964
|
+
function FpPow(Fp, num, power) {
|
|
1965
|
+
if (power < _0n$2)
|
|
1966
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
1967
|
+
if (power === _0n$2)
|
|
1968
|
+
return Fp.ONE;
|
|
1969
|
+
if (power === _1n$3)
|
|
1970
|
+
return num;
|
|
1971
|
+
let p = Fp.ONE;
|
|
1972
|
+
let d = num;
|
|
1973
|
+
while (power > _0n$2) {
|
|
1974
|
+
if (power & _1n$3)
|
|
1975
|
+
p = Fp.mul(p, d);
|
|
1976
|
+
d = Fp.sqr(d);
|
|
1977
|
+
power >>= _1n$3;
|
|
1978
|
+
}
|
|
1979
|
+
return p;
|
|
1980
|
+
}
|
|
1981
|
+
function FpInvertBatch(Fp, nums, passZero = false) {
|
|
1982
|
+
const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : void 0);
|
|
1983
|
+
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
1984
|
+
if (Fp.is0(num))
|
|
1985
|
+
return acc;
|
|
1986
|
+
inverted[i] = acc;
|
|
1987
|
+
return Fp.mul(acc, num);
|
|
1988
|
+
}, Fp.ONE);
|
|
1989
|
+
const invertedAcc = Fp.inv(multipliedAcc);
|
|
1990
|
+
nums.reduceRight((acc, num, i) => {
|
|
1991
|
+
if (Fp.is0(num))
|
|
1992
|
+
return acc;
|
|
1993
|
+
inverted[i] = Fp.mul(acc, inverted[i]);
|
|
1994
|
+
return Fp.mul(acc, num);
|
|
1995
|
+
}, invertedAcc);
|
|
1996
|
+
return inverted;
|
|
1997
|
+
}
|
|
1998
|
+
function FpLegendre(Fp, n) {
|
|
1999
|
+
const p1mod2 = (Fp.ORDER - _1n$3) / _2n$2;
|
|
2000
|
+
const powered = Fp.pow(n, p1mod2);
|
|
2001
|
+
const yes = Fp.eql(powered, Fp.ONE);
|
|
2002
|
+
const zero = Fp.eql(powered, Fp.ZERO);
|
|
2003
|
+
const no = Fp.eql(powered, Fp.neg(Fp.ONE));
|
|
2004
|
+
if (!yes && !zero && !no)
|
|
2005
|
+
throw new Error("invalid Legendre symbol result");
|
|
2006
|
+
return yes ? 1 : zero ? 0 : -1;
|
|
2007
|
+
}
|
|
2008
|
+
function nLength(n, nBitLength) {
|
|
2009
|
+
if (nBitLength !== void 0)
|
|
2010
|
+
anumber(nBitLength);
|
|
2011
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length;
|
|
2012
|
+
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
2013
|
+
return { nBitLength: _nBitLength, nByteLength };
|
|
2014
|
+
}
|
|
2015
|
+
class _Field {
|
|
2016
|
+
ORDER;
|
|
2017
|
+
BITS;
|
|
2018
|
+
BYTES;
|
|
2019
|
+
isLE;
|
|
2020
|
+
ZERO = _0n$2;
|
|
2021
|
+
ONE = _1n$3;
|
|
2022
|
+
_lengths;
|
|
2023
|
+
_sqrt;
|
|
2024
|
+
// cached sqrt
|
|
2025
|
+
_mod;
|
|
2026
|
+
constructor(ORDER, opts = {}) {
|
|
2027
|
+
if (ORDER <= _0n$2)
|
|
2028
|
+
throw new Error("invalid field: expected ORDER > 0, got " + ORDER);
|
|
2029
|
+
let _nbitLength = void 0;
|
|
2030
|
+
this.isLE = false;
|
|
2031
|
+
if (opts != null && typeof opts === "object") {
|
|
2032
|
+
if (typeof opts.BITS === "number")
|
|
2033
|
+
_nbitLength = opts.BITS;
|
|
2034
|
+
if (typeof opts.sqrt === "function")
|
|
2035
|
+
this.sqrt = opts.sqrt;
|
|
2036
|
+
if (typeof opts.isLE === "boolean")
|
|
2037
|
+
this.isLE = opts.isLE;
|
|
2038
|
+
if (opts.allowedLengths)
|
|
2039
|
+
this._lengths = opts.allowedLengths?.slice();
|
|
2040
|
+
if (typeof opts.modFromBytes === "boolean")
|
|
2041
|
+
this._mod = opts.modFromBytes;
|
|
2042
|
+
}
|
|
2043
|
+
const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);
|
|
2044
|
+
if (nByteLength > 2048)
|
|
2045
|
+
throw new Error("invalid field: expected ORDER of <= 2048 bytes");
|
|
2046
|
+
this.ORDER = ORDER;
|
|
2047
|
+
this.BITS = nBitLength;
|
|
2048
|
+
this.BYTES = nByteLength;
|
|
2049
|
+
this._sqrt = void 0;
|
|
2050
|
+
Object.preventExtensions(this);
|
|
1338
2051
|
}
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
|
1342
|
-
const a = _a;
|
|
1343
|
-
const A = M(X1 * X1);
|
|
1344
|
-
const B = M(Y1 * Y1);
|
|
1345
|
-
const C2 = M(2n * M(Z1 * Z1));
|
|
1346
|
-
const D = M(a * A);
|
|
1347
|
-
const x1y1 = X1 + Y1;
|
|
1348
|
-
const E = M(M(x1y1 * x1y1) - A - B);
|
|
1349
|
-
const G2 = D + B;
|
|
1350
|
-
const F = G2 - C2;
|
|
1351
|
-
const H = D - B;
|
|
1352
|
-
const X3 = M(E * F);
|
|
1353
|
-
const Y3 = M(G2 * H);
|
|
1354
|
-
const T3 = M(E * H);
|
|
1355
|
-
const Z3 = M(F * G2);
|
|
1356
|
-
return new Point(X3, Y3, Z3, T3);
|
|
2052
|
+
create(num) {
|
|
2053
|
+
return mod(num, this.ORDER);
|
|
1357
2054
|
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
const a = _a;
|
|
1363
|
-
const d = _d;
|
|
1364
|
-
const A = M(X1 * X2);
|
|
1365
|
-
const B = M(Y1 * Y2);
|
|
1366
|
-
const C2 = M(T1 * d * T2);
|
|
1367
|
-
const D = M(Z1 * Z2);
|
|
1368
|
-
const E = M((X1 + Y1) * (X2 + Y2) - A - B);
|
|
1369
|
-
const F = M(D - C2);
|
|
1370
|
-
const G2 = M(D + C2);
|
|
1371
|
-
const H = M(B - a * A);
|
|
1372
|
-
const X3 = M(E * F);
|
|
1373
|
-
const Y3 = M(G2 * H);
|
|
1374
|
-
const T3 = M(E * H);
|
|
1375
|
-
const Z3 = M(F * G2);
|
|
1376
|
-
return new Point(X3, Y3, Z3, T3);
|
|
2055
|
+
isValid(num) {
|
|
2056
|
+
if (typeof num !== "bigint")
|
|
2057
|
+
throw new Error("invalid field element: expected bigint, got " + typeof num);
|
|
2058
|
+
return _0n$2 <= num && num < this.ORDER;
|
|
1377
2059
|
}
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
* Uses {@link wNAF} for base point.
|
|
1381
|
-
* Uses fake point to mitigate side-channel leakage.
|
|
1382
|
-
* @param n scalar by which point is multiplied
|
|
1383
|
-
* @param safe safe mode guards against timing attacks; unsafe mode is faster
|
|
1384
|
-
*/
|
|
1385
|
-
multiply(n, safe = true) {
|
|
1386
|
-
if (!safe && (n === 0n || this.is0()))
|
|
1387
|
-
return I;
|
|
1388
|
-
arange(n, 1n, N);
|
|
1389
|
-
if (n === 1n)
|
|
1390
|
-
return this;
|
|
1391
|
-
if (this.equals(G))
|
|
1392
|
-
return wNAF(n).p;
|
|
1393
|
-
let p = I;
|
|
1394
|
-
let f = G;
|
|
1395
|
-
for (let d = this; n > 0n; d = d.double(), n >>= 1n) {
|
|
1396
|
-
if (n & 1n)
|
|
1397
|
-
p = p.add(d);
|
|
1398
|
-
else if (safe)
|
|
1399
|
-
f = f.add(d);
|
|
1400
|
-
}
|
|
1401
|
-
return p;
|
|
2060
|
+
is0(num) {
|
|
2061
|
+
return num === _0n$2;
|
|
1402
2062
|
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
if (this.equals(I))
|
|
1407
|
-
return { x: 0n, y: 1n };
|
|
1408
|
-
const iz = invert(z, P);
|
|
1409
|
-
if (M(z * iz) !== 1n)
|
|
1410
|
-
err("invalid inverse");
|
|
1411
|
-
return { x: M(x * iz), y: M(y * iz) };
|
|
2063
|
+
// is valid and invertible
|
|
2064
|
+
isValidNot0(num) {
|
|
2065
|
+
return !this.is0(num) && this.isValid(num);
|
|
1412
2066
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
const b = numTo32bLE(y);
|
|
1416
|
-
b[31] |= x & 1n ? 128 : 0;
|
|
1417
|
-
return b;
|
|
2067
|
+
isOdd(num) {
|
|
2068
|
+
return (num & _1n$3) === _1n$3;
|
|
1418
2069
|
}
|
|
1419
|
-
|
|
1420
|
-
return
|
|
2070
|
+
neg(num) {
|
|
2071
|
+
return mod(-num, this.ORDER);
|
|
1421
2072
|
}
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
return this.multiply(big(h), false);
|
|
2073
|
+
eql(lhs, rhs) {
|
|
2074
|
+
return lhs === rhs;
|
|
1425
2075
|
}
|
|
1426
|
-
|
|
1427
|
-
return this.
|
|
2076
|
+
sqr(num) {
|
|
2077
|
+
return mod(num * num, this.ORDER);
|
|
1428
2078
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
if (N % 2n)
|
|
1432
|
-
p = p.add(this);
|
|
1433
|
-
return p.is0();
|
|
2079
|
+
add(lhs, rhs) {
|
|
2080
|
+
return mod(lhs + rhs, this.ORDER);
|
|
1434
2081
|
}
|
|
1435
|
-
|
|
1436
|
-
return
|
|
2082
|
+
sub(lhs, rhs) {
|
|
2083
|
+
return mod(lhs - rhs, this.ORDER);
|
|
1437
2084
|
}
|
|
1438
|
-
|
|
1439
|
-
return this.
|
|
2085
|
+
mul(lhs, rhs) {
|
|
2086
|
+
return mod(lhs * rhs, this.ORDER);
|
|
1440
2087
|
}
|
|
1441
|
-
|
|
1442
|
-
return this
|
|
2088
|
+
pow(num, power) {
|
|
2089
|
+
return FpPow(this, num, power);
|
|
1443
2090
|
}
|
|
1444
|
-
|
|
1445
|
-
return this.
|
|
2091
|
+
div(lhs, rhs) {
|
|
2092
|
+
return mod(lhs * invert$1(rhs, this.ORDER), this.ORDER);
|
|
2093
|
+
}
|
|
2094
|
+
// Same as above, but doesn't normalize
|
|
2095
|
+
sqrN(num) {
|
|
2096
|
+
return num * num;
|
|
2097
|
+
}
|
|
2098
|
+
addN(lhs, rhs) {
|
|
2099
|
+
return lhs + rhs;
|
|
2100
|
+
}
|
|
2101
|
+
subN(lhs, rhs) {
|
|
2102
|
+
return lhs - rhs;
|
|
2103
|
+
}
|
|
2104
|
+
mulN(lhs, rhs) {
|
|
2105
|
+
return lhs * rhs;
|
|
2106
|
+
}
|
|
2107
|
+
inv(num) {
|
|
2108
|
+
return invert$1(num, this.ORDER);
|
|
2109
|
+
}
|
|
2110
|
+
sqrt(num) {
|
|
2111
|
+
if (!this._sqrt)
|
|
2112
|
+
this._sqrt = FpSqrt(this.ORDER);
|
|
2113
|
+
return this._sqrt(this, num);
|
|
2114
|
+
}
|
|
2115
|
+
toBytes(num) {
|
|
2116
|
+
return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
|
|
2117
|
+
}
|
|
2118
|
+
fromBytes(bytes, skipValidation = false) {
|
|
2119
|
+
abytes$1(bytes);
|
|
2120
|
+
const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;
|
|
2121
|
+
if (allowedLengths) {
|
|
2122
|
+
if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
2123
|
+
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
2124
|
+
}
|
|
2125
|
+
const padded = new Uint8Array(BYTES);
|
|
2126
|
+
padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
|
|
2127
|
+
bytes = padded;
|
|
2128
|
+
}
|
|
2129
|
+
if (bytes.length !== BYTES)
|
|
2130
|
+
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
2131
|
+
let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
2132
|
+
if (modFromBytes)
|
|
2133
|
+
scalar = mod(scalar, ORDER);
|
|
2134
|
+
if (!skipValidation) {
|
|
2135
|
+
if (!this.isValid(scalar))
|
|
2136
|
+
throw new Error("invalid field element: outside of range 0..ORDER");
|
|
2137
|
+
}
|
|
2138
|
+
return scalar;
|
|
2139
|
+
}
|
|
2140
|
+
// TODO: we don't need it here, move out to separate fn
|
|
2141
|
+
invertBatch(lst) {
|
|
2142
|
+
return FpInvertBatch(this, lst);
|
|
2143
|
+
}
|
|
2144
|
+
// We can't move this out because Fp6, Fp12 implement it
|
|
2145
|
+
// and it's unclear what to return in there.
|
|
2146
|
+
cmov(a, b, condition) {
|
|
2147
|
+
return condition ? b : a;
|
|
1446
2148
|
}
|
|
1447
2149
|
}
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
const
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
2150
|
+
function Field(ORDER, opts = {}) {
|
|
2151
|
+
return new _Field(ORDER, opts);
|
|
2152
|
+
}
|
|
2153
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2154
|
+
const _0n$1 = /* @__PURE__ */ BigInt(0);
|
|
2155
|
+
const _1n$2 = /* @__PURE__ */ BigInt(1);
|
|
2156
|
+
function negateCt(condition, item) {
|
|
2157
|
+
const neg = item.negate();
|
|
2158
|
+
return condition ? neg : item;
|
|
2159
|
+
}
|
|
2160
|
+
function normalizeZ(c, points) {
|
|
2161
|
+
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
2162
|
+
return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
|
|
2163
|
+
}
|
|
2164
|
+
function validateW(W2, bits) {
|
|
2165
|
+
if (!Number.isSafeInteger(W2) || W2 <= 0 || W2 > bits)
|
|
2166
|
+
throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W2);
|
|
2167
|
+
}
|
|
2168
|
+
function calcWOpts(W2, scalarBits2) {
|
|
2169
|
+
validateW(W2, scalarBits2);
|
|
2170
|
+
const windows = Math.ceil(scalarBits2 / W2) + 1;
|
|
2171
|
+
const windowSize = 2 ** (W2 - 1);
|
|
2172
|
+
const maxNumber = 2 ** W2;
|
|
2173
|
+
const mask = bitMask(W2);
|
|
2174
|
+
const shiftBy = BigInt(W2);
|
|
2175
|
+
return { windows, windowSize, mask, maxNumber, shiftBy };
|
|
2176
|
+
}
|
|
2177
|
+
function calcOffsets(n, window, wOpts) {
|
|
2178
|
+
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
|
2179
|
+
let wbits = Number(n & mask);
|
|
2180
|
+
let nextN = n >> shiftBy;
|
|
2181
|
+
if (wbits > windowSize) {
|
|
2182
|
+
wbits -= maxNumber;
|
|
2183
|
+
nextN += _1n$2;
|
|
2184
|
+
}
|
|
2185
|
+
const offsetStart = window * windowSize;
|
|
2186
|
+
const offset = offsetStart + Math.abs(wbits) - 1;
|
|
2187
|
+
const isZero = wbits === 0;
|
|
2188
|
+
const isNeg = wbits < 0;
|
|
2189
|
+
const isNegF = window % 2 !== 0;
|
|
2190
|
+
const offsetF = offsetStart;
|
|
2191
|
+
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
|
2192
|
+
}
|
|
2193
|
+
const pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
2194
|
+
const pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
2195
|
+
function getW(P2) {
|
|
2196
|
+
return pointWindowSizes.get(P2) || 1;
|
|
2197
|
+
}
|
|
2198
|
+
function assert0(n) {
|
|
2199
|
+
if (n !== _0n$1)
|
|
2200
|
+
throw new Error("invalid wNAF");
|
|
2201
|
+
}
|
|
2202
|
+
let wNAF$1 = class wNAF {
|
|
2203
|
+
BASE;
|
|
2204
|
+
ZERO;
|
|
2205
|
+
Fn;
|
|
2206
|
+
bits;
|
|
2207
|
+
// Parametrized with a given Point class (not individual point)
|
|
2208
|
+
constructor(Point2, bits) {
|
|
2209
|
+
this.BASE = Point2.BASE;
|
|
2210
|
+
this.ZERO = Point2.ZERO;
|
|
2211
|
+
this.Fn = Point2.Fn;
|
|
2212
|
+
this.bits = bits;
|
|
2213
|
+
}
|
|
2214
|
+
// non-const time multiplication ladder
|
|
2215
|
+
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
2216
|
+
let d = elm;
|
|
2217
|
+
while (n > _0n$1) {
|
|
2218
|
+
if (n & _1n$2)
|
|
2219
|
+
p = p.add(d);
|
|
2220
|
+
d = d.double();
|
|
2221
|
+
n >>= _1n$2;
|
|
2222
|
+
}
|
|
2223
|
+
return p;
|
|
1459
2224
|
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
2225
|
+
/**
|
|
2226
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
2227
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
2228
|
+
* Number of precomputed points depends on the curve size:
|
|
2229
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
2230
|
+
* - 𝑊 is the window size
|
|
2231
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
2232
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
2233
|
+
* @param point Point instance
|
|
2234
|
+
* @param W window size
|
|
2235
|
+
* @returns precomputed point tables flattened to a single array
|
|
2236
|
+
*/
|
|
2237
|
+
precomputeWindow(point, W2) {
|
|
2238
|
+
const { windows, windowSize } = calcWOpts(W2, this.bits);
|
|
2239
|
+
const points = [];
|
|
2240
|
+
let p = point;
|
|
2241
|
+
let base = p;
|
|
2242
|
+
for (let window = 0; window < windows; window++) {
|
|
2243
|
+
base = p;
|
|
2244
|
+
points.push(base);
|
|
2245
|
+
for (let i = 1; i < windowSize; i++) {
|
|
2246
|
+
base = base.add(p);
|
|
2247
|
+
points.push(base);
|
|
2248
|
+
}
|
|
2249
|
+
p = base.double();
|
|
2250
|
+
}
|
|
2251
|
+
return points;
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
2255
|
+
* More compact implementation:
|
|
2256
|
+
* https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
|
2257
|
+
* @returns real and fake (for const-time) points
|
|
2258
|
+
*/
|
|
2259
|
+
wNAF(W2, precomputes, n) {
|
|
2260
|
+
if (!this.Fn.isValid(n))
|
|
2261
|
+
throw new Error("invalid scalar");
|
|
2262
|
+
let p = this.ZERO;
|
|
2263
|
+
let f = this.BASE;
|
|
2264
|
+
const wo = calcWOpts(W2, this.bits);
|
|
2265
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
2266
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
|
2267
|
+
n = nextN;
|
|
2268
|
+
if (isZero) {
|
|
2269
|
+
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
2270
|
+
} else {
|
|
2271
|
+
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
assert0(n);
|
|
2275
|
+
return { p, f };
|
|
2276
|
+
}
|
|
2277
|
+
/**
|
|
2278
|
+
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
|
2279
|
+
* @param acc accumulator point to add result of multiplication
|
|
2280
|
+
* @returns point
|
|
2281
|
+
*/
|
|
2282
|
+
wNAFUnsafe(W2, precomputes, n, acc = this.ZERO) {
|
|
2283
|
+
const wo = calcWOpts(W2, this.bits);
|
|
2284
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
2285
|
+
if (n === _0n$1)
|
|
2286
|
+
break;
|
|
2287
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
2288
|
+
n = nextN;
|
|
2289
|
+
if (isZero) {
|
|
2290
|
+
continue;
|
|
2291
|
+
} else {
|
|
2292
|
+
const item = precomputes[offset];
|
|
2293
|
+
acc = acc.add(isNeg ? item.negate() : item);
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
assert0(n);
|
|
2297
|
+
return acc;
|
|
2298
|
+
}
|
|
2299
|
+
getPrecomputes(W2, point, transform) {
|
|
2300
|
+
let comp = pointPrecomputes.get(point);
|
|
2301
|
+
if (!comp) {
|
|
2302
|
+
comp = this.precomputeWindow(point, W2);
|
|
2303
|
+
if (W2 !== 1) {
|
|
2304
|
+
if (typeof transform === "function")
|
|
2305
|
+
comp = transform(comp);
|
|
2306
|
+
pointPrecomputes.set(point, comp);
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
return comp;
|
|
2310
|
+
}
|
|
2311
|
+
cached(point, scalar, transform) {
|
|
2312
|
+
const W2 = getW(point);
|
|
2313
|
+
return this.wNAF(W2, this.getPrecomputes(W2, point, transform), scalar);
|
|
2314
|
+
}
|
|
2315
|
+
unsafe(point, scalar, transform, prev) {
|
|
2316
|
+
const W2 = getW(point);
|
|
2317
|
+
if (W2 === 1)
|
|
2318
|
+
return this._unsafeLadder(point, scalar, prev);
|
|
2319
|
+
return this.wNAFUnsafe(W2, this.getPrecomputes(W2, point, transform), scalar, prev);
|
|
2320
|
+
}
|
|
2321
|
+
// We calculate precomputes for elliptic curve point multiplication
|
|
2322
|
+
// using windowed method. This specifies window size and
|
|
2323
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
|
2324
|
+
createCache(P2, W2) {
|
|
2325
|
+
validateW(W2, this.bits);
|
|
2326
|
+
pointWindowSizes.set(P2, W2);
|
|
2327
|
+
pointPrecomputes.delete(P2);
|
|
2328
|
+
}
|
|
2329
|
+
hasCache(elm) {
|
|
2330
|
+
return getW(elm) !== 1;
|
|
2331
|
+
}
|
|
2332
|
+
};
|
|
2333
|
+
function createField(order, field, isLE) {
|
|
2334
|
+
if (field) {
|
|
2335
|
+
if (field.ORDER !== order)
|
|
2336
|
+
throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
|
|
2337
|
+
validateField(field);
|
|
2338
|
+
return field;
|
|
2339
|
+
} else {
|
|
2340
|
+
return Field(order, { isLE });
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
2344
|
+
if (FpFnLE === void 0)
|
|
2345
|
+
FpFnLE = type === "edwards";
|
|
2346
|
+
if (!CURVE || typeof CURVE !== "object")
|
|
2347
|
+
throw new Error(`expected valid ${type} CURVE object`);
|
|
2348
|
+
for (const p of ["p", "n", "h"]) {
|
|
2349
|
+
const val = CURVE[p];
|
|
2350
|
+
if (!(typeof val === "bigint" && val > _0n$1))
|
|
2351
|
+
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
2352
|
+
}
|
|
2353
|
+
const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
2354
|
+
const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);
|
|
2355
|
+
const _b = "d";
|
|
2356
|
+
const params = ["Gx", "Gy", "a", _b];
|
|
2357
|
+
for (const p of params) {
|
|
2358
|
+
if (!Fp.isValid(CURVE[p]))
|
|
2359
|
+
throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
|
|
2360
|
+
}
|
|
2361
|
+
CURVE = Object.freeze(Object.assign({}, CURVE));
|
|
2362
|
+
return { CURVE, Fp, Fn };
|
|
2363
|
+
}
|
|
2364
|
+
function createKeygen(randomSecretKey, getPublicKey2) {
|
|
2365
|
+
return function keygen(seed) {
|
|
2366
|
+
const secretKey = randomSecretKey(seed);
|
|
2367
|
+
return { secretKey, publicKey: getPublicKey2(secretKey) };
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2371
|
+
const _0n = BigInt(0), _1n$1 = BigInt(1), _2n$1 = BigInt(2), _8n$1 = BigInt(8);
|
|
2372
|
+
function isEdValidXY(Fp, CURVE, x, y) {
|
|
2373
|
+
const x2 = Fp.sqr(x);
|
|
2374
|
+
const y2 = Fp.sqr(y);
|
|
2375
|
+
const left = Fp.add(Fp.mul(CURVE.a, x2), y2);
|
|
2376
|
+
const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2)));
|
|
2377
|
+
return Fp.eql(left, right);
|
|
2378
|
+
}
|
|
2379
|
+
function edwards(params, extraOpts = {}) {
|
|
2380
|
+
const validated = createCurveFields("edwards", params, extraOpts, extraOpts.FpFnLE);
|
|
2381
|
+
const { Fp, Fn } = validated;
|
|
2382
|
+
let CURVE = validated.CURVE;
|
|
2383
|
+
const { h: cofactor } = CURVE;
|
|
2384
|
+
validateObject(extraOpts, {}, { uvRatio: "function" });
|
|
2385
|
+
const MASK = _2n$1 << BigInt(Fn.BYTES * 8) - _1n$1;
|
|
2386
|
+
const modP = (n) => Fp.create(n);
|
|
2387
|
+
const uvRatio2 = extraOpts.uvRatio || ((u, v) => {
|
|
2388
|
+
try {
|
|
2389
|
+
return { isValid: true, value: Fp.sqrt(Fp.div(u, v)) };
|
|
2390
|
+
} catch (e) {
|
|
2391
|
+
return { isValid: false, value: _0n };
|
|
2392
|
+
}
|
|
2393
|
+
});
|
|
2394
|
+
if (!isEdValidXY(Fp, CURVE, CURVE.Gx, CURVE.Gy))
|
|
2395
|
+
throw new Error("bad curve params: generator point");
|
|
2396
|
+
function acoord(title, n, banZero = false) {
|
|
2397
|
+
const min = banZero ? _1n$1 : _0n;
|
|
2398
|
+
aInRange("coordinate " + title, n, min, MASK);
|
|
2399
|
+
return n;
|
|
2400
|
+
}
|
|
2401
|
+
function aedpoint(other) {
|
|
2402
|
+
if (!(other instanceof Point2))
|
|
2403
|
+
throw new Error("EdwardsPoint expected");
|
|
2404
|
+
}
|
|
2405
|
+
const toAffineMemo = memoized((p, iz) => {
|
|
2406
|
+
const { X, Y, Z } = p;
|
|
2407
|
+
const is0 = p.is0();
|
|
2408
|
+
if (iz == null)
|
|
2409
|
+
iz = is0 ? _8n$1 : Fp.inv(Z);
|
|
2410
|
+
const x = modP(X * iz);
|
|
2411
|
+
const y = modP(Y * iz);
|
|
2412
|
+
const zz = Fp.mul(Z, iz);
|
|
2413
|
+
if (is0)
|
|
2414
|
+
return { x: _0n, y: _1n$1 };
|
|
2415
|
+
if (zz !== _1n$1)
|
|
2416
|
+
throw new Error("invZ was invalid");
|
|
2417
|
+
return { x, y };
|
|
2418
|
+
});
|
|
2419
|
+
const assertValidMemo = memoized((p) => {
|
|
2420
|
+
const { a, d } = CURVE;
|
|
2421
|
+
if (p.is0())
|
|
2422
|
+
throw new Error("bad point: ZERO");
|
|
2423
|
+
const { X, Y, Z, T } = p;
|
|
2424
|
+
const X2 = modP(X * X);
|
|
2425
|
+
const Y2 = modP(Y * Y);
|
|
2426
|
+
const Z2 = modP(Z * Z);
|
|
2427
|
+
const Z4 = modP(Z2 * Z2);
|
|
2428
|
+
const aX2 = modP(X2 * a);
|
|
2429
|
+
const left = modP(Z2 * modP(aX2 + Y2));
|
|
2430
|
+
const right = modP(Z4 + modP(d * modP(X2 * Y2)));
|
|
2431
|
+
if (left !== right)
|
|
2432
|
+
throw new Error("bad point: equation left != right (1)");
|
|
2433
|
+
const XY = modP(X * Y);
|
|
2434
|
+
const ZT = modP(Z * T);
|
|
2435
|
+
if (XY !== ZT)
|
|
2436
|
+
throw new Error("bad point: equation left != right (2)");
|
|
2437
|
+
return true;
|
|
2438
|
+
});
|
|
2439
|
+
class Point2 {
|
|
2440
|
+
// base / generator point
|
|
2441
|
+
static BASE = new Point2(CURVE.Gx, CURVE.Gy, _1n$1, modP(CURVE.Gx * CURVE.Gy));
|
|
2442
|
+
// zero / infinity / identity point
|
|
2443
|
+
static ZERO = new Point2(_0n, _1n$1, _1n$1, _0n);
|
|
2444
|
+
// 0, 1, 1, 0
|
|
2445
|
+
// math field
|
|
2446
|
+
static Fp = Fp;
|
|
2447
|
+
// scalar field
|
|
2448
|
+
static Fn = Fn;
|
|
2449
|
+
X;
|
|
2450
|
+
Y;
|
|
2451
|
+
Z;
|
|
2452
|
+
T;
|
|
2453
|
+
constructor(X, Y, Z, T) {
|
|
2454
|
+
this.X = acoord("x", X);
|
|
2455
|
+
this.Y = acoord("y", Y);
|
|
2456
|
+
this.Z = acoord("z", Z, true);
|
|
2457
|
+
this.T = acoord("t", T);
|
|
2458
|
+
Object.freeze(this);
|
|
2459
|
+
}
|
|
2460
|
+
static CURVE() {
|
|
2461
|
+
return CURVE;
|
|
2462
|
+
}
|
|
2463
|
+
static fromAffine(p) {
|
|
2464
|
+
if (p instanceof Point2)
|
|
2465
|
+
throw new Error("extended point not allowed");
|
|
2466
|
+
const { x, y } = p || {};
|
|
2467
|
+
acoord("x", x);
|
|
2468
|
+
acoord("y", y);
|
|
2469
|
+
return new Point2(x, y, _1n$1, modP(x * y));
|
|
2470
|
+
}
|
|
2471
|
+
// Uses algo from RFC8032 5.1.3.
|
|
2472
|
+
static fromBytes(bytes, zip215 = false) {
|
|
2473
|
+
const len = Fp.BYTES;
|
|
2474
|
+
const { a, d } = CURVE;
|
|
2475
|
+
bytes = copyBytes(abytes$1(bytes, len, "point"));
|
|
2476
|
+
abool(zip215, "zip215");
|
|
2477
|
+
const normed = copyBytes(bytes);
|
|
2478
|
+
const lastByte = bytes[len - 1];
|
|
2479
|
+
normed[len - 1] = lastByte & -129;
|
|
2480
|
+
const y = bytesToNumberLE(normed);
|
|
2481
|
+
const max = zip215 ? MASK : Fp.ORDER;
|
|
2482
|
+
aInRange("point.y", y, _0n, max);
|
|
2483
|
+
const y2 = modP(y * y);
|
|
2484
|
+
const u = modP(y2 - _1n$1);
|
|
2485
|
+
const v = modP(d * y2 - a);
|
|
2486
|
+
let { isValid, value: x } = uvRatio2(u, v);
|
|
2487
|
+
if (!isValid)
|
|
2488
|
+
throw new Error("bad point: invalid y coordinate");
|
|
2489
|
+
const isXOdd = (x & _1n$1) === _1n$1;
|
|
2490
|
+
const isLastByteOdd = (lastByte & 128) !== 0;
|
|
2491
|
+
if (!zip215 && x === _0n && isLastByteOdd)
|
|
2492
|
+
throw new Error("bad point: x=0 and x_0=1");
|
|
2493
|
+
if (isLastByteOdd !== isXOdd)
|
|
2494
|
+
x = modP(-x);
|
|
2495
|
+
return Point2.fromAffine({ x, y });
|
|
2496
|
+
}
|
|
2497
|
+
static fromHex(hex, zip215 = false) {
|
|
2498
|
+
return Point2.fromBytes(hexToBytes$1(hex), zip215);
|
|
2499
|
+
}
|
|
2500
|
+
get x() {
|
|
2501
|
+
return this.toAffine().x;
|
|
2502
|
+
}
|
|
2503
|
+
get y() {
|
|
2504
|
+
return this.toAffine().y;
|
|
2505
|
+
}
|
|
2506
|
+
precompute(windowSize = 8, isLazy = true) {
|
|
2507
|
+
wnaf.createCache(this, windowSize);
|
|
2508
|
+
if (!isLazy)
|
|
2509
|
+
this.multiply(_2n$1);
|
|
2510
|
+
return this;
|
|
2511
|
+
}
|
|
2512
|
+
// Useful in fromAffine() - not for fromBytes(), which always created valid points.
|
|
2513
|
+
assertValidity() {
|
|
2514
|
+
assertValidMemo(this);
|
|
2515
|
+
}
|
|
2516
|
+
// Compare one point to another.
|
|
2517
|
+
equals(other) {
|
|
2518
|
+
aedpoint(other);
|
|
2519
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
2520
|
+
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
2521
|
+
const X1Z2 = modP(X1 * Z2);
|
|
2522
|
+
const X2Z1 = modP(X2 * Z1);
|
|
2523
|
+
const Y1Z2 = modP(Y1 * Z2);
|
|
2524
|
+
const Y2Z1 = modP(Y2 * Z1);
|
|
2525
|
+
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
2526
|
+
}
|
|
2527
|
+
is0() {
|
|
2528
|
+
return this.equals(Point2.ZERO);
|
|
2529
|
+
}
|
|
2530
|
+
negate() {
|
|
2531
|
+
return new Point2(modP(-this.X), this.Y, this.Z, modP(-this.T));
|
|
2532
|
+
}
|
|
2533
|
+
// Fast algo for doubling Extended Point.
|
|
2534
|
+
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
|
|
2535
|
+
// Cost: 4M + 4S + 1*a + 6add + 1*2.
|
|
2536
|
+
double() {
|
|
2537
|
+
const { a } = CURVE;
|
|
2538
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
2539
|
+
const A = modP(X1 * X1);
|
|
2540
|
+
const B = modP(Y1 * Y1);
|
|
2541
|
+
const C2 = modP(_2n$1 * modP(Z1 * Z1));
|
|
2542
|
+
const D = modP(a * A);
|
|
2543
|
+
const x1y1 = X1 + Y1;
|
|
2544
|
+
const E = modP(modP(x1y1 * x1y1) - A - B);
|
|
2545
|
+
const G2 = D + B;
|
|
2546
|
+
const F = G2 - C2;
|
|
2547
|
+
const H = D - B;
|
|
2548
|
+
const X3 = modP(E * F);
|
|
2549
|
+
const Y3 = modP(G2 * H);
|
|
2550
|
+
const T3 = modP(E * H);
|
|
2551
|
+
const Z3 = modP(F * G2);
|
|
2552
|
+
return new Point2(X3, Y3, Z3, T3);
|
|
2553
|
+
}
|
|
2554
|
+
// Fast algo for adding 2 Extended Points.
|
|
2555
|
+
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
|
2556
|
+
// Cost: 9M + 1*a + 1*d + 7add.
|
|
2557
|
+
add(other) {
|
|
2558
|
+
aedpoint(other);
|
|
2559
|
+
const { a, d } = CURVE;
|
|
2560
|
+
const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
|
|
2561
|
+
const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
|
|
2562
|
+
const A = modP(X1 * X2);
|
|
2563
|
+
const B = modP(Y1 * Y2);
|
|
2564
|
+
const C2 = modP(T1 * d * T2);
|
|
2565
|
+
const D = modP(Z1 * Z2);
|
|
2566
|
+
const E = modP((X1 + Y1) * (X2 + Y2) - A - B);
|
|
2567
|
+
const F = D - C2;
|
|
2568
|
+
const G2 = D + C2;
|
|
2569
|
+
const H = modP(B - a * A);
|
|
2570
|
+
const X3 = modP(E * F);
|
|
2571
|
+
const Y3 = modP(G2 * H);
|
|
2572
|
+
const T3 = modP(E * H);
|
|
2573
|
+
const Z3 = modP(F * G2);
|
|
2574
|
+
return new Point2(X3, Y3, Z3, T3);
|
|
2575
|
+
}
|
|
2576
|
+
subtract(other) {
|
|
2577
|
+
return this.add(other.negate());
|
|
2578
|
+
}
|
|
2579
|
+
// Constant-time multiplication.
|
|
2580
|
+
multiply(scalar) {
|
|
2581
|
+
if (!Fn.isValidNot0(scalar))
|
|
2582
|
+
throw new Error("invalid scalar: expected 1 <= sc < curve.n");
|
|
2583
|
+
const { p, f } = wnaf.cached(this, scalar, (p2) => normalizeZ(Point2, p2));
|
|
2584
|
+
return normalizeZ(Point2, [p, f])[0];
|
|
2585
|
+
}
|
|
2586
|
+
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
2587
|
+
// It's faster, but should only be used when you don't care about
|
|
2588
|
+
// an exposed private key e.g. sig verification.
|
|
2589
|
+
// Does NOT allow scalars higher than CURVE.n.
|
|
2590
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
|
2591
|
+
multiplyUnsafe(scalar, acc = Point2.ZERO) {
|
|
2592
|
+
if (!Fn.isValid(scalar))
|
|
2593
|
+
throw new Error("invalid scalar: expected 0 <= sc < curve.n");
|
|
2594
|
+
if (scalar === _0n)
|
|
2595
|
+
return Point2.ZERO;
|
|
2596
|
+
if (this.is0() || scalar === _1n$1)
|
|
2597
|
+
return this;
|
|
2598
|
+
return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point2, p), acc);
|
|
2599
|
+
}
|
|
2600
|
+
// Checks if point is of small order.
|
|
2601
|
+
// If you add something to small order point, you will have "dirty"
|
|
2602
|
+
// point with torsion component.
|
|
2603
|
+
// Multiplies point by cofactor and checks if the result is 0.
|
|
2604
|
+
isSmallOrder() {
|
|
2605
|
+
return this.multiplyUnsafe(cofactor).is0();
|
|
2606
|
+
}
|
|
2607
|
+
// Multiplies point by curve order and checks if the result is 0.
|
|
2608
|
+
// Returns `false` is the point is dirty.
|
|
2609
|
+
isTorsionFree() {
|
|
2610
|
+
return wnaf.unsafe(this, CURVE.n).is0();
|
|
2611
|
+
}
|
|
2612
|
+
// Converts Extended point to default (x, y) coordinates.
|
|
2613
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
2614
|
+
toAffine(invertedZ) {
|
|
2615
|
+
return toAffineMemo(this, invertedZ);
|
|
2616
|
+
}
|
|
2617
|
+
clearCofactor() {
|
|
2618
|
+
if (cofactor === _1n$1)
|
|
2619
|
+
return this;
|
|
2620
|
+
return this.multiplyUnsafe(cofactor);
|
|
2621
|
+
}
|
|
2622
|
+
toBytes() {
|
|
2623
|
+
const { x, y } = this.toAffine();
|
|
2624
|
+
const bytes = Fp.toBytes(y);
|
|
2625
|
+
bytes[bytes.length - 1] |= x & _1n$1 ? 128 : 0;
|
|
2626
|
+
return bytes;
|
|
2627
|
+
}
|
|
2628
|
+
toHex() {
|
|
2629
|
+
return bytesToHex$1(this.toBytes());
|
|
2630
|
+
}
|
|
2631
|
+
toString() {
|
|
2632
|
+
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
const wnaf = new wNAF$1(Point2, Fn.BITS);
|
|
2636
|
+
Point2.BASE.precompute(8);
|
|
2637
|
+
return Point2;
|
|
2638
|
+
}
|
|
2639
|
+
function eddsa(Point2, cHash, eddsaOpts = {}) {
|
|
2640
|
+
if (typeof cHash !== "function")
|
|
2641
|
+
throw new Error('"hash" function param is required');
|
|
2642
|
+
validateObject(eddsaOpts, {}, {
|
|
2643
|
+
adjustScalarBytes: "function",
|
|
2644
|
+
randomBytes: "function",
|
|
2645
|
+
domain: "function",
|
|
2646
|
+
prehash: "function",
|
|
2647
|
+
mapToCurve: "function"
|
|
2648
|
+
});
|
|
2649
|
+
const { prehash } = eddsaOpts;
|
|
2650
|
+
const { BASE, Fp, Fn } = Point2;
|
|
2651
|
+
const randomBytes2 = eddsaOpts.randomBytes || randomBytes$1;
|
|
2652
|
+
const adjustScalarBytes2 = eddsaOpts.adjustScalarBytes || ((bytes) => bytes);
|
|
2653
|
+
const domain = eddsaOpts.domain || ((data, ctx, phflag) => {
|
|
2654
|
+
abool(phflag, "phflag");
|
|
2655
|
+
if (ctx.length || phflag)
|
|
2656
|
+
throw new Error("Contexts/pre-hash are not supported");
|
|
2657
|
+
return data;
|
|
2658
|
+
});
|
|
2659
|
+
function modN_LE(hash) {
|
|
2660
|
+
return Fn.create(bytesToNumberLE(hash));
|
|
2661
|
+
}
|
|
2662
|
+
function getPrivateScalar(key) {
|
|
2663
|
+
const len = lengths.secretKey;
|
|
2664
|
+
abytes$1(key, lengths.secretKey, "secretKey");
|
|
2665
|
+
const hashed = abytes$1(cHash(key), 2 * len, "hashedSecretKey");
|
|
2666
|
+
const head = adjustScalarBytes2(hashed.slice(0, len));
|
|
2667
|
+
const prefix = hashed.slice(len, 2 * len);
|
|
2668
|
+
const scalar = modN_LE(head);
|
|
2669
|
+
return { head, prefix, scalar };
|
|
2670
|
+
}
|
|
2671
|
+
function getExtendedPublicKey2(secretKey) {
|
|
2672
|
+
const { head, prefix, scalar } = getPrivateScalar(secretKey);
|
|
2673
|
+
const point = BASE.multiply(scalar);
|
|
2674
|
+
const pointBytes = point.toBytes();
|
|
2675
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
2676
|
+
}
|
|
2677
|
+
function getPublicKey2(secretKey) {
|
|
2678
|
+
return getExtendedPublicKey2(secretKey).pointBytes;
|
|
2679
|
+
}
|
|
2680
|
+
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
|
2681
|
+
const msg = concatBytes$1(...msgs);
|
|
2682
|
+
return modN_LE(cHash(domain(msg, abytes$1(context, void 0, "context"), !!prehash)));
|
|
2683
|
+
}
|
|
2684
|
+
function sign(msg, secretKey, options = {}) {
|
|
2685
|
+
msg = abytes$1(msg, void 0, "message");
|
|
2686
|
+
if (prehash)
|
|
2687
|
+
msg = prehash(msg);
|
|
2688
|
+
const { prefix, scalar, pointBytes } = getExtendedPublicKey2(secretKey);
|
|
2689
|
+
const r = hashDomainToScalar(options.context, prefix, msg);
|
|
2690
|
+
const R = BASE.multiply(r).toBytes();
|
|
2691
|
+
const k = hashDomainToScalar(options.context, R, pointBytes, msg);
|
|
2692
|
+
const s = Fn.create(r + k * scalar);
|
|
2693
|
+
if (!Fn.isValid(s))
|
|
2694
|
+
throw new Error("sign failed: invalid s");
|
|
2695
|
+
const rs = concatBytes$1(R, Fn.toBytes(s));
|
|
2696
|
+
return abytes$1(rs, lengths.signature, "result");
|
|
2697
|
+
}
|
|
2698
|
+
const verifyOpts = { zip215: true };
|
|
2699
|
+
function verify(sig, msg, publicKey, options = verifyOpts) {
|
|
2700
|
+
const { context, zip215 } = options;
|
|
2701
|
+
const len = lengths.signature;
|
|
2702
|
+
sig = abytes$1(sig, len, "signature");
|
|
2703
|
+
msg = abytes$1(msg, void 0, "message");
|
|
2704
|
+
publicKey = abytes$1(publicKey, lengths.publicKey, "publicKey");
|
|
2705
|
+
if (zip215 !== void 0)
|
|
2706
|
+
abool(zip215, "zip215");
|
|
2707
|
+
if (prehash)
|
|
2708
|
+
msg = prehash(msg);
|
|
2709
|
+
const mid = len / 2;
|
|
2710
|
+
const r = sig.subarray(0, mid);
|
|
2711
|
+
const s = bytesToNumberLE(sig.subarray(mid, len));
|
|
2712
|
+
let A, R, SB;
|
|
2713
|
+
try {
|
|
2714
|
+
A = Point2.fromBytes(publicKey, zip215);
|
|
2715
|
+
R = Point2.fromBytes(r, zip215);
|
|
2716
|
+
SB = BASE.multiplyUnsafe(s);
|
|
2717
|
+
} catch (error) {
|
|
2718
|
+
return false;
|
|
2719
|
+
}
|
|
2720
|
+
if (!zip215 && A.isSmallOrder())
|
|
2721
|
+
return false;
|
|
2722
|
+
const k = hashDomainToScalar(context, R.toBytes(), A.toBytes(), msg);
|
|
2723
|
+
const RkA = R.add(A.multiplyUnsafe(k));
|
|
2724
|
+
return RkA.subtract(SB).clearCofactor().is0();
|
|
2725
|
+
}
|
|
2726
|
+
const _size = Fp.BYTES;
|
|
2727
|
+
const lengths = {
|
|
2728
|
+
secretKey: _size,
|
|
2729
|
+
publicKey: _size,
|
|
2730
|
+
signature: 2 * _size,
|
|
2731
|
+
seed: _size
|
|
2732
|
+
};
|
|
2733
|
+
function randomSecretKey(seed = randomBytes2(lengths.seed)) {
|
|
2734
|
+
return abytes$1(seed, lengths.seed, "seed");
|
|
2735
|
+
}
|
|
2736
|
+
function isValidSecretKey(key) {
|
|
2737
|
+
return isBytes$1(key) && key.length === Fn.BYTES;
|
|
2738
|
+
}
|
|
2739
|
+
function isValidPublicKey(key, zip215) {
|
|
2740
|
+
try {
|
|
2741
|
+
return !!Point2.fromBytes(key, zip215);
|
|
2742
|
+
} catch (error) {
|
|
2743
|
+
return false;
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
const utils2 = {
|
|
2747
|
+
getExtendedPublicKey: getExtendedPublicKey2,
|
|
2748
|
+
randomSecretKey,
|
|
2749
|
+
isValidSecretKey,
|
|
2750
|
+
isValidPublicKey,
|
|
2751
|
+
/**
|
|
2752
|
+
* Converts ed public key to x public key. Uses formula:
|
|
2753
|
+
* - ed25519:
|
|
2754
|
+
* - `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
|
2755
|
+
* - `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
|
2756
|
+
* - ed448:
|
|
2757
|
+
* - `(u, v) = ((y-1)/(y+1), sqrt(156324)*u/x)`
|
|
2758
|
+
* - `(x, y) = (sqrt(156324)*u/v, (1+u)/(1-u))`
|
|
2759
|
+
*/
|
|
2760
|
+
toMontgomery(publicKey) {
|
|
2761
|
+
const { y } = Point2.fromBytes(publicKey);
|
|
2762
|
+
const size = lengths.publicKey;
|
|
2763
|
+
const is25519 = size === 32;
|
|
2764
|
+
if (!is25519 && size !== 57)
|
|
2765
|
+
throw new Error("only defined for 25519 and 448");
|
|
2766
|
+
const u = is25519 ? Fp.div(_1n$1 + y, _1n$1 - y) : Fp.div(y - _1n$1, y + _1n$1);
|
|
2767
|
+
return Fp.toBytes(u);
|
|
2768
|
+
},
|
|
2769
|
+
toMontgomerySecret(secretKey) {
|
|
2770
|
+
const size = lengths.secretKey;
|
|
2771
|
+
abytes$1(secretKey, size);
|
|
2772
|
+
const hashed = cHash(secretKey.subarray(0, size));
|
|
2773
|
+
return adjustScalarBytes2(hashed).subarray(0, size);
|
|
2774
|
+
}
|
|
2775
|
+
};
|
|
2776
|
+
return Object.freeze({
|
|
2777
|
+
keygen: createKeygen(randomSecretKey, getPublicKey2),
|
|
2778
|
+
getPublicKey: getPublicKey2,
|
|
2779
|
+
sign,
|
|
2780
|
+
verify,
|
|
2781
|
+
utils: utils2,
|
|
2782
|
+
Point: Point2,
|
|
2783
|
+
lengths
|
|
2784
|
+
});
|
|
2785
|
+
}
|
|
2786
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2787
|
+
const _1n = BigInt(1), _2n = BigInt(2);
|
|
2788
|
+
const _5n = BigInt(5), _8n = BigInt(8);
|
|
2789
|
+
const ed25519_CURVE_p = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
2790
|
+
const ed25519_CURVE$1 = /* @__PURE__ */ (() => ({
|
|
2791
|
+
p: ed25519_CURVE_p,
|
|
2792
|
+
n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
|
|
2793
|
+
h: _8n,
|
|
2794
|
+
a: BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),
|
|
2795
|
+
d: BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),
|
|
2796
|
+
Gx: BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),
|
|
2797
|
+
Gy: BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")
|
|
2798
|
+
}))();
|
|
2799
|
+
function ed25519_pow_2_252_3(x) {
|
|
2800
|
+
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
|
2801
|
+
const P2 = ed25519_CURVE_p;
|
|
2802
|
+
const x2 = x * x % P2;
|
|
2803
|
+
const b2 = x2 * x % P2;
|
|
2804
|
+
const b4 = pow2$1(b2, _2n, P2) * b2 % P2;
|
|
2805
|
+
const b5 = pow2$1(b4, _1n, P2) * x % P2;
|
|
2806
|
+
const b10 = pow2$1(b5, _5n, P2) * b5 % P2;
|
|
2807
|
+
const b20 = pow2$1(b10, _10n, P2) * b10 % P2;
|
|
2808
|
+
const b40 = pow2$1(b20, _20n, P2) * b20 % P2;
|
|
2809
|
+
const b80 = pow2$1(b40, _40n, P2) * b40 % P2;
|
|
2810
|
+
const b160 = pow2$1(b80, _80n, P2) * b80 % P2;
|
|
2811
|
+
const b240 = pow2$1(b160, _80n, P2) * b80 % P2;
|
|
2812
|
+
const b250 = pow2$1(b240, _10n, P2) * b10 % P2;
|
|
2813
|
+
const pow_p_5_8 = pow2$1(b250, _2n, P2) * x % P2;
|
|
2814
|
+
return { pow_p_5_8, b2 };
|
|
2815
|
+
}
|
|
2816
|
+
function adjustScalarBytes(bytes) {
|
|
2817
|
+
bytes[0] &= 248;
|
|
2818
|
+
bytes[31] &= 127;
|
|
2819
|
+
bytes[31] |= 64;
|
|
2820
|
+
return bytes;
|
|
2821
|
+
}
|
|
2822
|
+
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
2823
|
+
function uvRatio$1(u, v) {
|
|
2824
|
+
const P2 = ed25519_CURVE_p;
|
|
2825
|
+
const v3 = mod(v * v * v, P2);
|
|
2826
|
+
const v7 = mod(v3 * v3 * v, P2);
|
|
2827
|
+
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
2828
|
+
let x = mod(u * v3 * pow, P2);
|
|
2829
|
+
const vx2 = mod(v * x * x, P2);
|
|
1484
2830
|
const root1 = x;
|
|
1485
|
-
const root2 =
|
|
2831
|
+
const root2 = mod(x * ED25519_SQRT_M1, P2);
|
|
1486
2832
|
const useRoot1 = vx2 === u;
|
|
1487
|
-
const useRoot2 = vx2 ===
|
|
1488
|
-
const noRoot = vx2 ===
|
|
2833
|
+
const useRoot2 = vx2 === mod(-u, P2);
|
|
2834
|
+
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P2);
|
|
1489
2835
|
if (useRoot1)
|
|
1490
2836
|
x = root1;
|
|
1491
2837
|
if (useRoot2 || noRoot)
|
|
1492
2838
|
x = root2;
|
|
1493
|
-
if ((
|
|
1494
|
-
x =
|
|
2839
|
+
if (isNegativeLE(x, P2))
|
|
2840
|
+
x = mod(-x, P2);
|
|
1495
2841
|
return { isValid: useRoot1 || useRoot2, value: x };
|
|
2842
|
+
}
|
|
2843
|
+
const ed25519_Point = /* @__PURE__ */ edwards(ed25519_CURVE$1, { uvRatio: uvRatio$1 });
|
|
2844
|
+
function ed(opts) {
|
|
2845
|
+
return eddsa(ed25519_Point, sha512, Object.assign({ adjustScalarBytes }, opts));
|
|
2846
|
+
}
|
|
2847
|
+
const ed25519 = /* @__PURE__ */ ed({});
|
|
2848
|
+
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
|
2849
|
+
const ed25519_CURVE = {
|
|
2850
|
+
p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
|
|
2851
|
+
n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,
|
|
2852
|
+
a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,
|
|
2853
|
+
d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,
|
|
2854
|
+
Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,
|
|
2855
|
+
Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n
|
|
1496
2856
|
};
|
|
1497
|
-
const
|
|
1498
|
-
const
|
|
1499
|
-
const
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
head[31] &= 127;
|
|
1504
|
-
head[31] |= 64;
|
|
1505
|
-
const prefix = hashed.slice(L, L2);
|
|
1506
|
-
const scalar = modL_LE(head);
|
|
1507
|
-
const point = G.multiply(scalar);
|
|
1508
|
-
const pointBytes = point.toBytes();
|
|
1509
|
-
return { head, prefix, scalar, point, pointBytes };
|
|
1510
|
-
};
|
|
1511
|
-
const getExtendedPublicKeyAsync = (priv) => sha512a(toU8(priv, L)).then(hash2extK);
|
|
1512
|
-
const getExtendedPublicKey = (priv) => hash2extK(sha512s(toU8(priv, L)));
|
|
1513
|
-
const getPublicKeyAsync = (priv) => getExtendedPublicKeyAsync(priv).then((p) => p.pointBytes);
|
|
1514
|
-
const getPublicKey = (priv) => getExtendedPublicKey(priv).pointBytes;
|
|
1515
|
-
const hashFinishA = (res) => sha512a(res.hashable).then(res.finish);
|
|
1516
|
-
const _sign = (e, rBytes, msg) => {
|
|
1517
|
-
const { pointBytes: P2, scalar: s } = e;
|
|
1518
|
-
const r = modL_LE(rBytes);
|
|
1519
|
-
const R = G.multiply(r).toBytes();
|
|
1520
|
-
const hashable = concatBytes(R, P2, msg);
|
|
1521
|
-
const finish = (hashed) => {
|
|
1522
|
-
const S = modN(r + modL_LE(hashed) * s);
|
|
1523
|
-
return abytes(concatBytes(R, numTo32bLE(S)), L2);
|
|
1524
|
-
};
|
|
1525
|
-
return { hashable, finish };
|
|
2857
|
+
const { p: P, n: N, Gx, Gy, a: _a, d: _d } = ed25519_CURVE;
|
|
2858
|
+
const h = 8n;
|
|
2859
|
+
const L = 32;
|
|
2860
|
+
const L2 = 64;
|
|
2861
|
+
const err = (m = "") => {
|
|
2862
|
+
throw new Error(m);
|
|
1526
2863
|
};
|
|
1527
|
-
const
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
2864
|
+
const isBig = (n) => typeof n === "bigint";
|
|
2865
|
+
const isStr = (s) => typeof s === "string";
|
|
2866
|
+
const isBytes = (a) => a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
2867
|
+
const abytes = (a, l) => !isBytes(a) || typeof l === "number" && l > 0 && a.length !== l ? err("Uint8Array expected") : a;
|
|
2868
|
+
const u8n = (len) => new Uint8Array(len);
|
|
2869
|
+
const u8fr = (buf) => Uint8Array.from(buf);
|
|
2870
|
+
const padh = (n, pad) => n.toString(16).padStart(pad, "0");
|
|
2871
|
+
const bytesToHex = (b) => Array.from(abytes(b)).map((e) => padh(e, 2)).join("");
|
|
2872
|
+
const C = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
2873
|
+
const _ch = (ch) => {
|
|
2874
|
+
if (ch >= C._0 && ch <= C._9)
|
|
2875
|
+
return ch - C._0;
|
|
2876
|
+
if (ch >= C.A && ch <= C.F)
|
|
2877
|
+
return ch - (C.A - 10);
|
|
2878
|
+
if (ch >= C.a && ch <= C.f)
|
|
2879
|
+
return ch - (C.a - 10);
|
|
2880
|
+
return;
|
|
1532
2881
|
};
|
|
1533
|
-
const
|
|
1534
|
-
const
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
const
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
let
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
SB = G.multiply(s, false);
|
|
1549
|
-
hashable = concatBytes(R.toBytes(), A.toBytes(), msg);
|
|
1550
|
-
} catch (error) {
|
|
2882
|
+
const hexToBytes = (hex) => {
|
|
2883
|
+
const e = "hex invalid";
|
|
2884
|
+
if (!isStr(hex))
|
|
2885
|
+
return err(e);
|
|
2886
|
+
const hl = hex.length;
|
|
2887
|
+
const al = hl / 2;
|
|
2888
|
+
if (hl % 2)
|
|
2889
|
+
return err(e);
|
|
2890
|
+
const array = u8n(al);
|
|
2891
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
2892
|
+
const n1 = _ch(hex.charCodeAt(hi));
|
|
2893
|
+
const n2 = _ch(hex.charCodeAt(hi + 1));
|
|
2894
|
+
if (n1 === void 0 || n2 === void 0)
|
|
2895
|
+
return err(e);
|
|
2896
|
+
array[ai] = n1 * 16 + n2;
|
|
1551
2897
|
}
|
|
1552
|
-
|
|
1553
|
-
if (SB == null)
|
|
1554
|
-
return false;
|
|
1555
|
-
if (!zip215 && A.isSmallOrder())
|
|
1556
|
-
return false;
|
|
1557
|
-
const k = modL_LE(hashed);
|
|
1558
|
-
const RkA = R.add(A.multiply(k, false));
|
|
1559
|
-
return RkA.add(SB.negate()).clearCofactor().is0();
|
|
1560
|
-
};
|
|
1561
|
-
return { hashable, finish };
|
|
2898
|
+
return array;
|
|
1562
2899
|
};
|
|
1563
|
-
const
|
|
1564
|
-
const
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
mod: M,
|
|
1575
|
-
invert,
|
|
1576
|
-
randomBytes
|
|
2900
|
+
const toU8 = (a, len) => abytes(isStr(a) ? hexToBytes(a) : u8fr(abytes(a)), len);
|
|
2901
|
+
const cr = () => globalThis?.crypto;
|
|
2902
|
+
const subtle = () => cr()?.subtle ?? err("crypto.subtle must be defined");
|
|
2903
|
+
const concatBytes = (...arrs) => {
|
|
2904
|
+
const r = u8n(arrs.reduce((sum, a) => sum + abytes(a).length, 0));
|
|
2905
|
+
let pad = 0;
|
|
2906
|
+
arrs.forEach((a) => {
|
|
2907
|
+
r.set(a, pad);
|
|
2908
|
+
pad += a.length;
|
|
2909
|
+
});
|
|
2910
|
+
return r;
|
|
1577
2911
|
};
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
randomPrivateKey: () => randomBytes(L),
|
|
1582
|
-
precompute: (w = 8, p = G) => {
|
|
1583
|
-
p.multiply(3n);
|
|
1584
|
-
return p;
|
|
1585
|
-
}
|
|
1586
|
-
// no-op
|
|
2912
|
+
const randomBytes = (len = L) => {
|
|
2913
|
+
const c = cr();
|
|
2914
|
+
return c.getRandomValues(u8n(len));
|
|
1587
2915
|
};
|
|
1588
|
-
const
|
|
1589
|
-
const
|
|
1590
|
-
const
|
|
1591
|
-
const
|
|
1592
|
-
|
|
1593
|
-
const points = [];
|
|
1594
|
-
let p = G;
|
|
1595
|
-
let b = p;
|
|
1596
|
-
for (let w = 0; w < pwindows; w++) {
|
|
1597
|
-
b = p;
|
|
1598
|
-
points.push(b);
|
|
1599
|
-
for (let i = 1; i < pwindowSize; i++) {
|
|
1600
|
-
b = b.add(p);
|
|
1601
|
-
points.push(b);
|
|
1602
|
-
}
|
|
1603
|
-
p = b.double();
|
|
1604
|
-
}
|
|
1605
|
-
return points;
|
|
1606
|
-
};
|
|
1607
|
-
let Gpows = void 0;
|
|
1608
|
-
const ctneg = (cnd, p) => {
|
|
1609
|
-
const n = p.negate();
|
|
1610
|
-
return cnd ? n : p;
|
|
2916
|
+
const big = BigInt;
|
|
2917
|
+
const arange = (n, min, max, msg = "bad number: out of range") => isBig(n) && min <= n && n < max ? n : err(msg);
|
|
2918
|
+
const M = (a, b = P) => {
|
|
2919
|
+
const r = a % b;
|
|
2920
|
+
return r >= 0n ? r : b + r;
|
|
1611
2921
|
};
|
|
1612
|
-
const
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
let wbits = Number(n & mask);
|
|
1622
|
-
n >>= shiftBy;
|
|
1623
|
-
if (wbits > pwindowSize) {
|
|
1624
|
-
wbits -= maxNum;
|
|
1625
|
-
n += 1n;
|
|
1626
|
-
}
|
|
1627
|
-
const off = w * pwindowSize;
|
|
1628
|
-
const offF = off;
|
|
1629
|
-
const offP = off + Math.abs(wbits) - 1;
|
|
1630
|
-
const isEven = w % 2 !== 0;
|
|
1631
|
-
const isNeg = wbits < 0;
|
|
1632
|
-
if (wbits === 0) {
|
|
1633
|
-
f = f.add(ctneg(isEven, comp[offF]));
|
|
1634
|
-
} else {
|
|
1635
|
-
p = p.add(ctneg(isNeg, comp[offP]));
|
|
1636
|
-
}
|
|
2922
|
+
const modN = (a) => M(a, N);
|
|
2923
|
+
const invert = (num, md) => {
|
|
2924
|
+
if (num === 0n || md <= 0n)
|
|
2925
|
+
err("no inverse n=" + num + " mod=" + md);
|
|
2926
|
+
let a = M(num, md), b = md, x = 0n, u = 1n;
|
|
2927
|
+
while (a !== 0n) {
|
|
2928
|
+
const q = b / a, r = b % a;
|
|
2929
|
+
const m = x - u * q;
|
|
2930
|
+
b = a, a = r, x = u, u = m;
|
|
1637
2931
|
}
|
|
1638
|
-
return
|
|
1639
|
-
};
|
|
1640
|
-
var __defProp = Object.defineProperty;
|
|
1641
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1642
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1643
|
-
const jsonBodySerializer = {
|
|
1644
|
-
bodySerializer: (body) => JSON.stringify(
|
|
1645
|
-
body,
|
|
1646
|
-
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
1647
|
-
)
|
|
1648
|
-
};
|
|
1649
|
-
const createSseClient = ({
|
|
1650
|
-
onRequest,
|
|
1651
|
-
onSseError,
|
|
1652
|
-
onSseEvent,
|
|
1653
|
-
responseTransformer,
|
|
1654
|
-
responseValidator,
|
|
1655
|
-
sseDefaultRetryDelay,
|
|
1656
|
-
sseMaxRetryAttempts,
|
|
1657
|
-
sseMaxRetryDelay,
|
|
1658
|
-
sseSleepFn,
|
|
1659
|
-
url,
|
|
1660
|
-
...options
|
|
1661
|
-
}) => {
|
|
1662
|
-
let lastEventId;
|
|
1663
|
-
const sleep = sseSleepFn ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
1664
|
-
const createStream = async function* () {
|
|
1665
|
-
let retryDelay = sseDefaultRetryDelay ?? 3e3;
|
|
1666
|
-
let attempt = 0;
|
|
1667
|
-
const signal = options.signal ?? new AbortController().signal;
|
|
1668
|
-
while (true) {
|
|
1669
|
-
if (signal.aborted) break;
|
|
1670
|
-
attempt++;
|
|
1671
|
-
const headers = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
1672
|
-
if (lastEventId !== void 0) {
|
|
1673
|
-
headers.set("Last-Event-ID", lastEventId);
|
|
1674
|
-
}
|
|
1675
|
-
try {
|
|
1676
|
-
const requestInit = {
|
|
1677
|
-
redirect: "follow",
|
|
1678
|
-
...options,
|
|
1679
|
-
body: options.serializedBody,
|
|
1680
|
-
headers,
|
|
1681
|
-
signal
|
|
1682
|
-
};
|
|
1683
|
-
let request = new Request(url, requestInit);
|
|
1684
|
-
if (onRequest) {
|
|
1685
|
-
request = await onRequest(url, requestInit);
|
|
1686
|
-
}
|
|
1687
|
-
const _fetch = options.fetch ?? globalThis.fetch;
|
|
1688
|
-
const response = await _fetch(request);
|
|
1689
|
-
if (!response.ok)
|
|
1690
|
-
throw new Error(
|
|
1691
|
-
`SSE failed: ${response.status} ${response.statusText}`
|
|
1692
|
-
);
|
|
1693
|
-
if (!response.body) throw new Error("No body in SSE response");
|
|
1694
|
-
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader();
|
|
1695
|
-
let buffer = "";
|
|
1696
|
-
const abortHandler = () => {
|
|
1697
|
-
try {
|
|
1698
|
-
reader.cancel();
|
|
1699
|
-
} catch {
|
|
1700
|
-
}
|
|
1701
|
-
};
|
|
1702
|
-
signal.addEventListener("abort", abortHandler);
|
|
1703
|
-
try {
|
|
1704
|
-
while (true) {
|
|
1705
|
-
const { done, value } = await reader.read();
|
|
1706
|
-
if (done) break;
|
|
1707
|
-
buffer += value;
|
|
1708
|
-
buffer = buffer.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1709
|
-
const chunks = buffer.split("\n\n");
|
|
1710
|
-
buffer = chunks.pop() ?? "";
|
|
1711
|
-
for (const chunk of chunks) {
|
|
1712
|
-
const lines = chunk.split("\n");
|
|
1713
|
-
const dataLines = [];
|
|
1714
|
-
let eventName;
|
|
1715
|
-
for (const line of lines) {
|
|
1716
|
-
if (line.startsWith("data:")) {
|
|
1717
|
-
dataLines.push(line.replace(/^data:\s*/, ""));
|
|
1718
|
-
} else if (line.startsWith("event:")) {
|
|
1719
|
-
eventName = line.replace(/^event:\s*/, "");
|
|
1720
|
-
} else if (line.startsWith("id:")) {
|
|
1721
|
-
lastEventId = line.replace(/^id:\s*/, "");
|
|
1722
|
-
} else if (line.startsWith("retry:")) {
|
|
1723
|
-
const parsed = Number.parseInt(
|
|
1724
|
-
line.replace(/^retry:\s*/, ""),
|
|
1725
|
-
10
|
|
1726
|
-
);
|
|
1727
|
-
if (!Number.isNaN(parsed)) {
|
|
1728
|
-
retryDelay = parsed;
|
|
1729
|
-
}
|
|
1730
|
-
}
|
|
1731
|
-
}
|
|
1732
|
-
let data;
|
|
1733
|
-
let parsedJson = false;
|
|
1734
|
-
if (dataLines.length) {
|
|
1735
|
-
const rawData = dataLines.join("\n");
|
|
1736
|
-
try {
|
|
1737
|
-
data = JSON.parse(rawData);
|
|
1738
|
-
parsedJson = true;
|
|
1739
|
-
} catch {
|
|
1740
|
-
data = rawData;
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
if (parsedJson) {
|
|
1744
|
-
if (responseValidator) {
|
|
1745
|
-
await responseValidator(data);
|
|
1746
|
-
}
|
|
1747
|
-
if (responseTransformer) {
|
|
1748
|
-
data = await responseTransformer(data);
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
onSseEvent == null ? void 0 : onSseEvent({
|
|
1752
|
-
data,
|
|
1753
|
-
event: eventName,
|
|
1754
|
-
id: lastEventId,
|
|
1755
|
-
retry: retryDelay
|
|
1756
|
-
});
|
|
1757
|
-
if (dataLines.length) {
|
|
1758
|
-
yield data;
|
|
1759
|
-
}
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1762
|
-
} finally {
|
|
1763
|
-
signal.removeEventListener("abort", abortHandler);
|
|
1764
|
-
reader.releaseLock();
|
|
1765
|
-
}
|
|
1766
|
-
break;
|
|
1767
|
-
} catch (error) {
|
|
1768
|
-
onSseError == null ? void 0 : onSseError(error);
|
|
1769
|
-
if (sseMaxRetryAttempts !== void 0 && attempt >= sseMaxRetryAttempts) {
|
|
1770
|
-
break;
|
|
1771
|
-
}
|
|
1772
|
-
const backoff = Math.min(
|
|
1773
|
-
retryDelay * 2 ** (attempt - 1),
|
|
1774
|
-
sseMaxRetryDelay ?? 3e4
|
|
1775
|
-
);
|
|
1776
|
-
await sleep(backoff);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
};
|
|
1780
|
-
const stream = createStream();
|
|
1781
|
-
return { stream };
|
|
2932
|
+
return b === 1n ? M(x, md) : err("no inverse");
|
|
1782
2933
|
};
|
|
1783
|
-
const
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
return ";";
|
|
1789
|
-
case "simple":
|
|
1790
|
-
return ",";
|
|
1791
|
-
default:
|
|
1792
|
-
return "&";
|
|
1793
|
-
}
|
|
2934
|
+
const callHash = (name2) => {
|
|
2935
|
+
const fn = etc[name2];
|
|
2936
|
+
if (typeof fn !== "function")
|
|
2937
|
+
err("hashes." + name2 + " not set");
|
|
2938
|
+
return fn;
|
|
1794
2939
|
};
|
|
1795
|
-
const
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
2940
|
+
const apoint = (p) => p instanceof Point ? p : err("Point expected");
|
|
2941
|
+
const B256 = 2n ** 256n;
|
|
2942
|
+
class Point {
|
|
2943
|
+
static BASE;
|
|
2944
|
+
static ZERO;
|
|
2945
|
+
ex;
|
|
2946
|
+
ey;
|
|
2947
|
+
ez;
|
|
2948
|
+
et;
|
|
2949
|
+
constructor(ex, ey, ez, et) {
|
|
2950
|
+
const max = B256;
|
|
2951
|
+
this.ex = arange(ex, 0n, max);
|
|
2952
|
+
this.ey = arange(ey, 0n, max);
|
|
2953
|
+
this.ez = arange(ez, 1n, max);
|
|
2954
|
+
this.et = arange(et, 0n, max);
|
|
2955
|
+
Object.freeze(this);
|
|
1805
2956
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
switch (style) {
|
|
1809
|
-
case "label":
|
|
1810
|
-
return ".";
|
|
1811
|
-
case "matrix":
|
|
1812
|
-
return ";";
|
|
1813
|
-
case "simple":
|
|
1814
|
-
return ",";
|
|
1815
|
-
default:
|
|
1816
|
-
return "&";
|
|
2957
|
+
static fromAffine(p) {
|
|
2958
|
+
return new Point(p.x, p.y, 1n, M(p.x * p.y));
|
|
1817
2959
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
const
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
const joinedValues = value.map((v) => {
|
|
1841
|
-
if (style === "label" || style === "simple") {
|
|
1842
|
-
return allowReserved ? v : encodeURIComponent(v);
|
|
1843
|
-
}
|
|
1844
|
-
return serializePrimitiveParam({
|
|
1845
|
-
allowReserved,
|
|
1846
|
-
name: name2,
|
|
1847
|
-
value: v
|
|
1848
|
-
});
|
|
1849
|
-
}).join(separator);
|
|
1850
|
-
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
1851
|
-
};
|
|
1852
|
-
const serializePrimitiveParam = ({
|
|
1853
|
-
allowReserved,
|
|
1854
|
-
name: name2,
|
|
1855
|
-
value
|
|
1856
|
-
}) => {
|
|
1857
|
-
if (value === void 0 || value === null) {
|
|
1858
|
-
return "";
|
|
1859
|
-
}
|
|
1860
|
-
if (typeof value === "object") {
|
|
1861
|
-
throw new Error(
|
|
1862
|
-
"Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these."
|
|
1863
|
-
);
|
|
2960
|
+
/** RFC8032 5.1.3: Uint8Array to Point. */
|
|
2961
|
+
static fromBytes(hex, zip215 = false) {
|
|
2962
|
+
const d = _d;
|
|
2963
|
+
const normed = u8fr(abytes(hex, L));
|
|
2964
|
+
const lastByte = hex[31];
|
|
2965
|
+
normed[31] = lastByte & -129;
|
|
2966
|
+
const y = bytesToNumLE(normed);
|
|
2967
|
+
const max = zip215 ? B256 : P;
|
|
2968
|
+
arange(y, 0n, max);
|
|
2969
|
+
const y2 = M(y * y);
|
|
2970
|
+
const u = M(y2 - 1n);
|
|
2971
|
+
const v = M(d * y2 + 1n);
|
|
2972
|
+
let { isValid, value: x } = uvRatio(u, v);
|
|
2973
|
+
if (!isValid)
|
|
2974
|
+
err("bad point: y not sqrt");
|
|
2975
|
+
const isXOdd = (x & 1n) === 1n;
|
|
2976
|
+
const isLastByteOdd = (lastByte & 128) !== 0;
|
|
2977
|
+
if (!zip215 && x === 0n && isLastByteOdd)
|
|
2978
|
+
err("bad point: x==0, isLastByteOdd");
|
|
2979
|
+
if (isLastByteOdd !== isXOdd)
|
|
2980
|
+
x = M(-x);
|
|
2981
|
+
return new Point(x, y, 1n, M(x * y));
|
|
1864
2982
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
const
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2983
|
+
/** Checks if the point is valid and on-curve. */
|
|
2984
|
+
assertValidity() {
|
|
2985
|
+
const a = _a;
|
|
2986
|
+
const d = _d;
|
|
2987
|
+
const p = this;
|
|
2988
|
+
if (p.is0())
|
|
2989
|
+
throw new Error("bad point: ZERO");
|
|
2990
|
+
const { ex: X, ey: Y, ez: Z, et: T } = p;
|
|
2991
|
+
const X2 = M(X * X);
|
|
2992
|
+
const Y2 = M(Y * Y);
|
|
2993
|
+
const Z2 = M(Z * Z);
|
|
2994
|
+
const Z4 = M(Z2 * Z2);
|
|
2995
|
+
const aX2 = M(X2 * a);
|
|
2996
|
+
const left = M(Z2 * M(aX2 + Y2));
|
|
2997
|
+
const right = M(Z4 + M(d * M(X2 * Y2)));
|
|
2998
|
+
if (left !== right)
|
|
2999
|
+
throw new Error("bad point: equation left != right (1)");
|
|
3000
|
+
const XY = M(X * Y);
|
|
3001
|
+
const ZT = M(Z * T);
|
|
3002
|
+
if (XY !== ZT)
|
|
3003
|
+
throw new Error("bad point: equation left != right (2)");
|
|
3004
|
+
return this;
|
|
1877
3005
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
const joinedValues2 = values2.join(",");
|
|
1888
|
-
switch (style) {
|
|
1889
|
-
case "form":
|
|
1890
|
-
return `${name2}=${joinedValues2}`;
|
|
1891
|
-
case "label":
|
|
1892
|
-
return `.${joinedValues2}`;
|
|
1893
|
-
case "matrix":
|
|
1894
|
-
return `;${name2}=${joinedValues2}`;
|
|
1895
|
-
default:
|
|
1896
|
-
return joinedValues2;
|
|
1897
|
-
}
|
|
3006
|
+
/** Equality check: compare points P&Q. */
|
|
3007
|
+
equals(other) {
|
|
3008
|
+
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
|
3009
|
+
const { ex: X2, ey: Y2, ez: Z2 } = apoint(other);
|
|
3010
|
+
const X1Z2 = M(X1 * Z2);
|
|
3011
|
+
const X2Z1 = M(X2 * Z1);
|
|
3012
|
+
const Y1Z2 = M(Y1 * Z2);
|
|
3013
|
+
const Y2Z1 = M(Y2 * Z1);
|
|
3014
|
+
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
|
1898
3015
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
([key, v]) => serializePrimitiveParam({
|
|
1902
|
-
allowReserved,
|
|
1903
|
-
name: style === "deepObject" ? `${name2}[${key}]` : key,
|
|
1904
|
-
value: v
|
|
1905
|
-
})
|
|
1906
|
-
).join(separator);
|
|
1907
|
-
return style === "label" || style === "matrix" ? separator + joinedValues : joinedValues;
|
|
1908
|
-
};
|
|
1909
|
-
const PATH_PARAM_RE = /\{[^{}]+\}/g;
|
|
1910
|
-
const defaultPathSerializer = ({ path, url: _url }) => {
|
|
1911
|
-
let url = _url;
|
|
1912
|
-
const matches = _url.match(PATH_PARAM_RE);
|
|
1913
|
-
if (matches) {
|
|
1914
|
-
for (const match of matches) {
|
|
1915
|
-
let explode = false;
|
|
1916
|
-
let name2 = match.substring(1, match.length - 1);
|
|
1917
|
-
let style = "simple";
|
|
1918
|
-
if (name2.endsWith("*")) {
|
|
1919
|
-
explode = true;
|
|
1920
|
-
name2 = name2.substring(0, name2.length - 1);
|
|
1921
|
-
}
|
|
1922
|
-
if (name2.startsWith(".")) {
|
|
1923
|
-
name2 = name2.substring(1);
|
|
1924
|
-
style = "label";
|
|
1925
|
-
} else if (name2.startsWith(";")) {
|
|
1926
|
-
name2 = name2.substring(1);
|
|
1927
|
-
style = "matrix";
|
|
1928
|
-
}
|
|
1929
|
-
const value = path[name2];
|
|
1930
|
-
if (value === void 0 || value === null) {
|
|
1931
|
-
continue;
|
|
1932
|
-
}
|
|
1933
|
-
if (Array.isArray(value)) {
|
|
1934
|
-
url = url.replace(
|
|
1935
|
-
match,
|
|
1936
|
-
serializeArrayParam({ explode, name: name2, style, value })
|
|
1937
|
-
);
|
|
1938
|
-
continue;
|
|
1939
|
-
}
|
|
1940
|
-
if (typeof value === "object") {
|
|
1941
|
-
url = url.replace(
|
|
1942
|
-
match,
|
|
1943
|
-
serializeObjectParam({
|
|
1944
|
-
explode,
|
|
1945
|
-
name: name2,
|
|
1946
|
-
style,
|
|
1947
|
-
value,
|
|
1948
|
-
valueOnly: true
|
|
1949
|
-
})
|
|
1950
|
-
);
|
|
1951
|
-
continue;
|
|
1952
|
-
}
|
|
1953
|
-
if (style === "matrix") {
|
|
1954
|
-
url = url.replace(
|
|
1955
|
-
match,
|
|
1956
|
-
`;${serializePrimitiveParam({
|
|
1957
|
-
name: name2,
|
|
1958
|
-
value
|
|
1959
|
-
})}`
|
|
1960
|
-
);
|
|
1961
|
-
continue;
|
|
1962
|
-
}
|
|
1963
|
-
const replaceValue = encodeURIComponent(
|
|
1964
|
-
style === "label" ? `.${value}` : value
|
|
1965
|
-
);
|
|
1966
|
-
url = url.replace(match, replaceValue);
|
|
1967
|
-
}
|
|
3016
|
+
is0() {
|
|
3017
|
+
return this.equals(I);
|
|
1968
3018
|
}
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
baseUrl,
|
|
1973
|
-
path,
|
|
1974
|
-
query,
|
|
1975
|
-
querySerializer,
|
|
1976
|
-
url: _url
|
|
1977
|
-
}) => {
|
|
1978
|
-
const pathUrl = _url.startsWith("/") ? _url : `/${_url}`;
|
|
1979
|
-
let url = (baseUrl ?? "") + pathUrl;
|
|
1980
|
-
if (path) {
|
|
1981
|
-
url = defaultPathSerializer({ path, url });
|
|
3019
|
+
/** Flip point over y coordinate. */
|
|
3020
|
+
negate() {
|
|
3021
|
+
return new Point(M(-this.ex), this.ey, this.ez, M(-this.et));
|
|
1982
3022
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
3023
|
+
/** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */
|
|
3024
|
+
double() {
|
|
3025
|
+
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
|
3026
|
+
const a = _a;
|
|
3027
|
+
const A = M(X1 * X1);
|
|
3028
|
+
const B = M(Y1 * Y1);
|
|
3029
|
+
const C2 = M(2n * M(Z1 * Z1));
|
|
3030
|
+
const D = M(a * A);
|
|
3031
|
+
const x1y1 = X1 + Y1;
|
|
3032
|
+
const E = M(M(x1y1 * x1y1) - A - B);
|
|
3033
|
+
const G2 = D + B;
|
|
3034
|
+
const F = G2 - C2;
|
|
3035
|
+
const H = D - B;
|
|
3036
|
+
const X3 = M(E * F);
|
|
3037
|
+
const Y3 = M(G2 * H);
|
|
3038
|
+
const T3 = M(E * H);
|
|
3039
|
+
const Z3 = M(F * G2);
|
|
3040
|
+
return new Point(X3, Y3, Z3, T3);
|
|
1986
3041
|
}
|
|
1987
|
-
|
|
1988
|
-
|
|
3042
|
+
/** Point addition. Complete formula. Cost: `8M + 1*k + 8add + 1*2`. */
|
|
3043
|
+
add(other) {
|
|
3044
|
+
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
|
3045
|
+
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = apoint(other);
|
|
3046
|
+
const a = _a;
|
|
3047
|
+
const d = _d;
|
|
3048
|
+
const A = M(X1 * X2);
|
|
3049
|
+
const B = M(Y1 * Y2);
|
|
3050
|
+
const C2 = M(T1 * d * T2);
|
|
3051
|
+
const D = M(Z1 * Z2);
|
|
3052
|
+
const E = M((X1 + Y1) * (X2 + Y2) - A - B);
|
|
3053
|
+
const F = M(D - C2);
|
|
3054
|
+
const G2 = M(D + C2);
|
|
3055
|
+
const H = M(B - a * A);
|
|
3056
|
+
const X3 = M(E * F);
|
|
3057
|
+
const Y3 = M(G2 * H);
|
|
3058
|
+
const T3 = M(E * H);
|
|
3059
|
+
const Z3 = M(F * G2);
|
|
3060
|
+
return new Point(X3, Y3, Z3, T3);
|
|
1989
3061
|
}
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
3062
|
+
/**
|
|
3063
|
+
* Point-by-scalar multiplication. Scalar must be in range 1 <= n < CURVE.n.
|
|
3064
|
+
* Uses {@link wNAF} for base point.
|
|
3065
|
+
* Uses fake point to mitigate side-channel leakage.
|
|
3066
|
+
* @param n scalar by which point is multiplied
|
|
3067
|
+
* @param safe safe mode guards against timing attacks; unsafe mode is faster
|
|
3068
|
+
*/
|
|
3069
|
+
multiply(n, safe = true) {
|
|
3070
|
+
if (!safe && (n === 0n || this.is0()))
|
|
3071
|
+
return I;
|
|
3072
|
+
arange(n, 1n, N);
|
|
3073
|
+
if (n === 1n)
|
|
3074
|
+
return this;
|
|
3075
|
+
if (this.equals(G))
|
|
3076
|
+
return wNAF2(n).p;
|
|
3077
|
+
let p = I;
|
|
3078
|
+
let f = G;
|
|
3079
|
+
for (let d = this; n > 0n; d = d.double(), n >>= 1n) {
|
|
3080
|
+
if (n & 1n)
|
|
3081
|
+
p = p.add(d);
|
|
3082
|
+
else if (safe)
|
|
3083
|
+
f = f.add(d);
|
|
1999
3084
|
}
|
|
2000
|
-
return
|
|
2001
|
-
}
|
|
2002
|
-
if (hasBody) {
|
|
2003
|
-
return options.body;
|
|
3085
|
+
return p;
|
|
2004
3086
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
const
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
3087
|
+
/** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */
|
|
3088
|
+
toAffine() {
|
|
3089
|
+
const { ex: x, ey: y, ez: z } = this;
|
|
3090
|
+
if (this.equals(I))
|
|
3091
|
+
return { x: 0n, y: 1n };
|
|
3092
|
+
const iz = invert(z, P);
|
|
3093
|
+
if (M(z * iz) !== 1n)
|
|
3094
|
+
err("invalid inverse");
|
|
3095
|
+
return { x: M(x * iz), y: M(y * iz) };
|
|
2011
3096
|
}
|
|
2012
|
-
|
|
2013
|
-
|
|
3097
|
+
toBytes() {
|
|
3098
|
+
const { x, y } = this.assertValidity().toAffine();
|
|
3099
|
+
const b = numTo32bLE(y);
|
|
3100
|
+
b[31] |= x & 1n ? 128 : 0;
|
|
3101
|
+
return b;
|
|
2014
3102
|
}
|
|
2015
|
-
|
|
2016
|
-
return
|
|
3103
|
+
toHex() {
|
|
3104
|
+
return bytesToHex(this.toBytes());
|
|
2017
3105
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
parameters = {},
|
|
2022
|
-
...args
|
|
2023
|
-
} = {}) => {
|
|
2024
|
-
const querySerializer = (queryParams) => {
|
|
2025
|
-
const search = [];
|
|
2026
|
-
if (queryParams && typeof queryParams === "object") {
|
|
2027
|
-
for (const name2 in queryParams) {
|
|
2028
|
-
const value = queryParams[name2];
|
|
2029
|
-
if (value === void 0 || value === null) {
|
|
2030
|
-
continue;
|
|
2031
|
-
}
|
|
2032
|
-
const options = parameters[name2] || args;
|
|
2033
|
-
if (Array.isArray(value)) {
|
|
2034
|
-
const serializedArray = serializeArrayParam({
|
|
2035
|
-
allowReserved: options.allowReserved,
|
|
2036
|
-
explode: true,
|
|
2037
|
-
name: name2,
|
|
2038
|
-
style: "form",
|
|
2039
|
-
value,
|
|
2040
|
-
...options.array
|
|
2041
|
-
});
|
|
2042
|
-
if (serializedArray) search.push(serializedArray);
|
|
2043
|
-
} else if (typeof value === "object") {
|
|
2044
|
-
const serializedObject = serializeObjectParam({
|
|
2045
|
-
allowReserved: options.allowReserved,
|
|
2046
|
-
explode: true,
|
|
2047
|
-
name: name2,
|
|
2048
|
-
style: "deepObject",
|
|
2049
|
-
value,
|
|
2050
|
-
...options.object
|
|
2051
|
-
});
|
|
2052
|
-
if (serializedObject) search.push(serializedObject);
|
|
2053
|
-
} else {
|
|
2054
|
-
const serializedPrimitive = serializePrimitiveParam({
|
|
2055
|
-
allowReserved: options.allowReserved,
|
|
2056
|
-
name: name2,
|
|
2057
|
-
value
|
|
2058
|
-
});
|
|
2059
|
-
if (serializedPrimitive) search.push(serializedPrimitive);
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
}
|
|
2063
|
-
return search.join("&");
|
|
2064
|
-
};
|
|
2065
|
-
return querySerializer;
|
|
2066
|
-
};
|
|
2067
|
-
const getParseAs = (contentType) => {
|
|
2068
|
-
var _a2;
|
|
2069
|
-
if (!contentType) {
|
|
2070
|
-
return "stream";
|
|
3106
|
+
// encode to hex string
|
|
3107
|
+
clearCofactor() {
|
|
3108
|
+
return this.multiply(big(h), false);
|
|
2071
3109
|
}
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
return;
|
|
3110
|
+
isSmallOrder() {
|
|
3111
|
+
return this.clearCofactor().is0();
|
|
2075
3112
|
}
|
|
2076
|
-
|
|
2077
|
-
|
|
3113
|
+
isTorsionFree() {
|
|
3114
|
+
let p = this.multiply(N / 2n, false).double();
|
|
3115
|
+
if (N % 2n)
|
|
3116
|
+
p = p.add(this);
|
|
3117
|
+
return p.is0();
|
|
2078
3118
|
}
|
|
2079
|
-
|
|
2080
|
-
return
|
|
3119
|
+
static fromHex(hex, zip215) {
|
|
3120
|
+
return Point.fromBytes(toU8(hex), zip215);
|
|
2081
3121
|
}
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
)) {
|
|
2085
|
-
return "blob";
|
|
3122
|
+
get x() {
|
|
3123
|
+
return this.toAffine().x;
|
|
2086
3124
|
}
|
|
2087
|
-
|
|
2088
|
-
return
|
|
3125
|
+
get y() {
|
|
3126
|
+
return this.toAffine().y;
|
|
2089
3127
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
const checkForExistence = (options, name2) => {
|
|
2093
|
-
var _a2, _b;
|
|
2094
|
-
if (!name2) {
|
|
2095
|
-
return false;
|
|
3128
|
+
toRawBytes() {
|
|
3129
|
+
return this.toBytes();
|
|
2096
3130
|
}
|
|
2097
|
-
|
|
2098
|
-
|
|
3131
|
+
}
|
|
3132
|
+
const G = new Point(Gx, Gy, 1n, M(Gx * Gy));
|
|
3133
|
+
const I = new Point(0n, 1n, 1n, 0n);
|
|
3134
|
+
Point.BASE = G;
|
|
3135
|
+
Point.ZERO = I;
|
|
3136
|
+
const numTo32bLE = (num) => hexToBytes(padh(arange(num, 0n, B256), L2)).reverse();
|
|
3137
|
+
const bytesToNumLE = (b) => big("0x" + bytesToHex(u8fr(abytes(b)).reverse()));
|
|
3138
|
+
const pow2 = (x, power) => {
|
|
3139
|
+
let r = x;
|
|
3140
|
+
while (power-- > 0n) {
|
|
3141
|
+
r *= r;
|
|
3142
|
+
r %= P;
|
|
2099
3143
|
}
|
|
2100
|
-
return
|
|
3144
|
+
return r;
|
|
2101
3145
|
};
|
|
2102
|
-
const
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
case "query":
|
|
2117
|
-
if (!options.query) {
|
|
2118
|
-
options.query = {};
|
|
2119
|
-
}
|
|
2120
|
-
options.query[name2] = token;
|
|
2121
|
-
break;
|
|
2122
|
-
case "cookie":
|
|
2123
|
-
options.headers.append("Cookie", `${name2}=${token}`);
|
|
2124
|
-
break;
|
|
2125
|
-
case "header":
|
|
2126
|
-
default:
|
|
2127
|
-
options.headers.set(name2, token);
|
|
2128
|
-
break;
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
3146
|
+
const pow_2_252_3 = (x) => {
|
|
3147
|
+
const x2 = x * x % P;
|
|
3148
|
+
const b2 = x2 * x % P;
|
|
3149
|
+
const b4 = pow2(b2, 2n) * b2 % P;
|
|
3150
|
+
const b5 = pow2(b4, 1n) * x % P;
|
|
3151
|
+
const b10 = pow2(b5, 5n) * b5 % P;
|
|
3152
|
+
const b20 = pow2(b10, 10n) * b10 % P;
|
|
3153
|
+
const b40 = pow2(b20, 20n) * b20 % P;
|
|
3154
|
+
const b80 = pow2(b40, 40n) * b40 % P;
|
|
3155
|
+
const b160 = pow2(b80, 80n) * b80 % P;
|
|
3156
|
+
const b240 = pow2(b160, 80n) * b80 % P;
|
|
3157
|
+
const b250 = pow2(b240, 10n) * b10 % P;
|
|
3158
|
+
const pow_p_5_8 = pow2(b250, 2n) * x % P;
|
|
3159
|
+
return { pow_p_5_8, b2 };
|
|
2131
3160
|
};
|
|
2132
|
-
const
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
const
|
|
2140
|
-
|
|
2141
|
-
const
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
3161
|
+
const RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n;
|
|
3162
|
+
const uvRatio = (u, v) => {
|
|
3163
|
+
const v3 = M(v * v * v);
|
|
3164
|
+
const v7 = M(v3 * v3 * v);
|
|
3165
|
+
const pow = pow_2_252_3(u * v7).pow_p_5_8;
|
|
3166
|
+
let x = M(u * v3 * pow);
|
|
3167
|
+
const vx2 = M(v * x * x);
|
|
3168
|
+
const root1 = x;
|
|
3169
|
+
const root2 = M(x * RM1);
|
|
3170
|
+
const useRoot1 = vx2 === u;
|
|
3171
|
+
const useRoot2 = vx2 === M(-u);
|
|
3172
|
+
const noRoot = vx2 === M(-u * RM1);
|
|
3173
|
+
if (useRoot1)
|
|
3174
|
+
x = root1;
|
|
3175
|
+
if (useRoot2 || noRoot)
|
|
3176
|
+
x = root2;
|
|
3177
|
+
if ((M(x) & 1n) === 1n)
|
|
3178
|
+
x = M(-x);
|
|
3179
|
+
return { isValid: useRoot1 || useRoot2, value: x };
|
|
2147
3180
|
};
|
|
2148
|
-
const
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
3181
|
+
const modL_LE = (hash) => modN(bytesToNumLE(hash));
|
|
3182
|
+
const sha512a = (...m) => etc.sha512Async(...m);
|
|
3183
|
+
const sha512s = (...m) => callHash("sha512Sync")(...m);
|
|
3184
|
+
const hash2extK = (hashed) => {
|
|
3185
|
+
const head = hashed.slice(0, L);
|
|
3186
|
+
head[0] &= 248;
|
|
3187
|
+
head[31] &= 127;
|
|
3188
|
+
head[31] |= 64;
|
|
3189
|
+
const prefix = hashed.slice(L, L2);
|
|
3190
|
+
const scalar = modL_LE(head);
|
|
3191
|
+
const point = G.multiply(scalar);
|
|
3192
|
+
const pointBytes = point.toBytes();
|
|
3193
|
+
return { head, prefix, scalar, point, pointBytes };
|
|
2154
3194
|
};
|
|
2155
|
-
const
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
mergedHeaders.set(
|
|
2171
|
-
key,
|
|
2172
|
-
typeof value === "object" ? JSON.stringify(value) : value
|
|
2173
|
-
);
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
return mergedHeaders;
|
|
3195
|
+
const getExtendedPublicKeyAsync = (priv) => sha512a(toU8(priv, L)).then(hash2extK);
|
|
3196
|
+
const getExtendedPublicKey = (priv) => hash2extK(sha512s(toU8(priv, L)));
|
|
3197
|
+
const getPublicKeyAsync = (priv) => getExtendedPublicKeyAsync(priv).then((p) => p.pointBytes);
|
|
3198
|
+
const getPublicKey = (priv) => getExtendedPublicKey(priv).pointBytes;
|
|
3199
|
+
const hashFinishA = (res) => sha512a(res.hashable).then(res.finish);
|
|
3200
|
+
const _sign = (e, rBytes, msg) => {
|
|
3201
|
+
const { pointBytes: P2, scalar: s } = e;
|
|
3202
|
+
const r = modL_LE(rBytes);
|
|
3203
|
+
const R = G.multiply(r).toBytes();
|
|
3204
|
+
const hashable = concatBytes(R, P2, msg);
|
|
3205
|
+
const finish = (hashed) => {
|
|
3206
|
+
const S = modN(r + modL_LE(hashed) * s);
|
|
3207
|
+
return abytes(concatBytes(R, numTo32bLE(S)), L2);
|
|
3208
|
+
};
|
|
3209
|
+
return { hashable, finish };
|
|
2178
3210
|
};
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
this.fns = [];
|
|
2185
|
-
}
|
|
2186
|
-
eject(id) {
|
|
2187
|
-
const index = this.getInterceptorIndex(id);
|
|
2188
|
-
if (this.fns[index]) {
|
|
2189
|
-
this.fns[index] = null;
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
exists(id) {
|
|
2193
|
-
const index = this.getInterceptorIndex(id);
|
|
2194
|
-
return Boolean(this.fns[index]);
|
|
2195
|
-
}
|
|
2196
|
-
getInterceptorIndex(id) {
|
|
2197
|
-
if (typeof id === "number") {
|
|
2198
|
-
return this.fns[id] ? id : -1;
|
|
2199
|
-
}
|
|
2200
|
-
return this.fns.indexOf(id);
|
|
2201
|
-
}
|
|
2202
|
-
update(id, fn) {
|
|
2203
|
-
const index = this.getInterceptorIndex(id);
|
|
2204
|
-
if (this.fns[index]) {
|
|
2205
|
-
this.fns[index] = fn;
|
|
2206
|
-
return id;
|
|
2207
|
-
}
|
|
2208
|
-
return false;
|
|
2209
|
-
}
|
|
2210
|
-
use(fn) {
|
|
2211
|
-
this.fns.push(fn);
|
|
2212
|
-
return this.fns.length - 1;
|
|
2213
|
-
}
|
|
2214
|
-
}
|
|
2215
|
-
const createInterceptors = () => ({
|
|
2216
|
-
error: new Interceptors2(),
|
|
2217
|
-
request: new Interceptors2(),
|
|
2218
|
-
response: new Interceptors2()
|
|
2219
|
-
});
|
|
2220
|
-
const defaultQuerySerializer = createQuerySerializer({
|
|
2221
|
-
allowReserved: false,
|
|
2222
|
-
array: {
|
|
2223
|
-
explode: true,
|
|
2224
|
-
style: "form"
|
|
2225
|
-
},
|
|
2226
|
-
object: {
|
|
2227
|
-
explode: true,
|
|
2228
|
-
style: "deepObject"
|
|
2229
|
-
}
|
|
2230
|
-
});
|
|
2231
|
-
const defaultHeaders = {
|
|
2232
|
-
"Content-Type": "application/json"
|
|
3211
|
+
const signAsync = async (msg, privKey) => {
|
|
3212
|
+
const m = toU8(msg);
|
|
3213
|
+
const e = await getExtendedPublicKeyAsync(privKey);
|
|
3214
|
+
const rBytes = await sha512a(e.prefix, m);
|
|
3215
|
+
return hashFinishA(_sign(e, rBytes, m));
|
|
2233
3216
|
};
|
|
2234
|
-
const
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
let
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
});
|
|
2262
|
-
}
|
|
2263
|
-
if (opts.requestValidator) {
|
|
2264
|
-
await opts.requestValidator(opts);
|
|
2265
|
-
}
|
|
2266
|
-
if (opts.body !== void 0 && opts.bodySerializer) {
|
|
2267
|
-
opts.serializedBody = opts.bodySerializer(opts.body);
|
|
2268
|
-
}
|
|
2269
|
-
if (opts.body === void 0 || opts.serializedBody === "") {
|
|
2270
|
-
opts.headers.delete("Content-Type");
|
|
2271
|
-
}
|
|
2272
|
-
const url = buildUrl(opts);
|
|
2273
|
-
return { opts, url };
|
|
2274
|
-
};
|
|
2275
|
-
const request = async (options) => {
|
|
2276
|
-
const { opts, url } = await beforeRequest(options);
|
|
2277
|
-
const requestInit = {
|
|
2278
|
-
redirect: "follow",
|
|
2279
|
-
...opts,
|
|
2280
|
-
body: getValidRequestBody(opts)
|
|
2281
|
-
};
|
|
2282
|
-
let request2 = new Request(url, requestInit);
|
|
2283
|
-
for (const fn of interceptors.request.fns) {
|
|
2284
|
-
if (fn) {
|
|
2285
|
-
request2 = await fn(request2, opts);
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
const _fetch = opts.fetch;
|
|
2289
|
-
let response;
|
|
2290
|
-
try {
|
|
2291
|
-
response = await _fetch(request2);
|
|
2292
|
-
} catch (error2) {
|
|
2293
|
-
let finalError2 = error2;
|
|
2294
|
-
for (const fn of interceptors.error.fns) {
|
|
2295
|
-
if (fn) {
|
|
2296
|
-
finalError2 = await fn(
|
|
2297
|
-
error2,
|
|
2298
|
-
void 0,
|
|
2299
|
-
request2,
|
|
2300
|
-
opts
|
|
2301
|
-
);
|
|
2302
|
-
}
|
|
2303
|
-
}
|
|
2304
|
-
finalError2 = finalError2 || {};
|
|
2305
|
-
if (opts.throwOnError) {
|
|
2306
|
-
throw finalError2;
|
|
2307
|
-
}
|
|
2308
|
-
return opts.responseStyle === "data" ? void 0 : {
|
|
2309
|
-
error: finalError2,
|
|
2310
|
-
request: request2,
|
|
2311
|
-
response: void 0
|
|
2312
|
-
};
|
|
2313
|
-
}
|
|
2314
|
-
for (const fn of interceptors.response.fns) {
|
|
2315
|
-
if (fn) {
|
|
2316
|
-
response = await fn(response, request2, opts);
|
|
2317
|
-
}
|
|
2318
|
-
}
|
|
2319
|
-
const result = {
|
|
2320
|
-
request: request2,
|
|
2321
|
-
response
|
|
2322
|
-
};
|
|
2323
|
-
if (response.ok) {
|
|
2324
|
-
const parseAs = (opts.parseAs === "auto" ? getParseAs(response.headers.get("Content-Type")) : opts.parseAs) ?? "json";
|
|
2325
|
-
if (response.status === 204 || response.headers.get("Content-Length") === "0") {
|
|
2326
|
-
let emptyData;
|
|
2327
|
-
switch (parseAs) {
|
|
2328
|
-
case "arrayBuffer":
|
|
2329
|
-
case "blob":
|
|
2330
|
-
case "text":
|
|
2331
|
-
emptyData = await response[parseAs]();
|
|
2332
|
-
break;
|
|
2333
|
-
case "formData":
|
|
2334
|
-
emptyData = new FormData();
|
|
2335
|
-
break;
|
|
2336
|
-
case "stream":
|
|
2337
|
-
emptyData = response.body;
|
|
2338
|
-
break;
|
|
2339
|
-
case "json":
|
|
2340
|
-
default:
|
|
2341
|
-
emptyData = {};
|
|
2342
|
-
break;
|
|
2343
|
-
}
|
|
2344
|
-
return opts.responseStyle === "data" ? emptyData : {
|
|
2345
|
-
data: emptyData,
|
|
2346
|
-
...result
|
|
2347
|
-
};
|
|
2348
|
-
}
|
|
2349
|
-
let data;
|
|
2350
|
-
switch (parseAs) {
|
|
2351
|
-
case "arrayBuffer":
|
|
2352
|
-
case "blob":
|
|
2353
|
-
case "formData":
|
|
2354
|
-
case "json":
|
|
2355
|
-
case "text":
|
|
2356
|
-
data = await response[parseAs]();
|
|
2357
|
-
break;
|
|
2358
|
-
case "stream":
|
|
2359
|
-
return opts.responseStyle === "data" ? response.body : {
|
|
2360
|
-
data: response.body,
|
|
2361
|
-
...result
|
|
2362
|
-
};
|
|
2363
|
-
}
|
|
2364
|
-
if (parseAs === "json") {
|
|
2365
|
-
if (opts.responseValidator) {
|
|
2366
|
-
await opts.responseValidator(data);
|
|
2367
|
-
}
|
|
2368
|
-
if (opts.responseTransformer) {
|
|
2369
|
-
data = await opts.responseTransformer(data);
|
|
2370
|
-
}
|
|
2371
|
-
}
|
|
2372
|
-
return opts.responseStyle === "data" ? data : {
|
|
2373
|
-
data,
|
|
2374
|
-
...result
|
|
2375
|
-
};
|
|
2376
|
-
}
|
|
2377
|
-
const textError = await response.text();
|
|
2378
|
-
let jsonError;
|
|
2379
|
-
try {
|
|
2380
|
-
jsonError = JSON.parse(textError);
|
|
2381
|
-
} catch {
|
|
2382
|
-
}
|
|
2383
|
-
const error = jsonError ?? textError;
|
|
2384
|
-
let finalError = error;
|
|
2385
|
-
for (const fn of interceptors.error.fns) {
|
|
2386
|
-
if (fn) {
|
|
2387
|
-
finalError = await fn(error, response, request2, opts);
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
finalError = finalError || {};
|
|
2391
|
-
if (opts.throwOnError) {
|
|
2392
|
-
throw finalError;
|
|
2393
|
-
}
|
|
2394
|
-
return opts.responseStyle === "data" ? void 0 : {
|
|
2395
|
-
error: finalError,
|
|
2396
|
-
...result
|
|
2397
|
-
};
|
|
2398
|
-
};
|
|
2399
|
-
const makeMethodFn = (method) => (options) => request({ ...options, method });
|
|
2400
|
-
const makeSseFn = (method) => async (options) => {
|
|
2401
|
-
const { opts, url } = await beforeRequest(options);
|
|
2402
|
-
return createSseClient({
|
|
2403
|
-
...opts,
|
|
2404
|
-
body: opts.body,
|
|
2405
|
-
headers: opts.headers,
|
|
2406
|
-
method,
|
|
2407
|
-
onRequest: async (url2, init) => {
|
|
2408
|
-
let request2 = new Request(url2, init);
|
|
2409
|
-
for (const fn of interceptors.request.fns) {
|
|
2410
|
-
if (fn) {
|
|
2411
|
-
request2 = await fn(request2, opts);
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2414
|
-
return request2;
|
|
2415
|
-
},
|
|
2416
|
-
url
|
|
2417
|
-
});
|
|
2418
|
-
};
|
|
2419
|
-
return {
|
|
2420
|
-
buildUrl,
|
|
2421
|
-
connect: makeMethodFn("CONNECT"),
|
|
2422
|
-
delete: makeMethodFn("DELETE"),
|
|
2423
|
-
get: makeMethodFn("GET"),
|
|
2424
|
-
getConfig,
|
|
2425
|
-
head: makeMethodFn("HEAD"),
|
|
2426
|
-
interceptors,
|
|
2427
|
-
options: makeMethodFn("OPTIONS"),
|
|
2428
|
-
patch: makeMethodFn("PATCH"),
|
|
2429
|
-
post: makeMethodFn("POST"),
|
|
2430
|
-
put: makeMethodFn("PUT"),
|
|
2431
|
-
request,
|
|
2432
|
-
setConfig,
|
|
2433
|
-
sse: {
|
|
2434
|
-
connect: makeSseFn("CONNECT"),
|
|
2435
|
-
delete: makeSseFn("DELETE"),
|
|
2436
|
-
get: makeSseFn("GET"),
|
|
2437
|
-
head: makeSseFn("HEAD"),
|
|
2438
|
-
options: makeSseFn("OPTIONS"),
|
|
2439
|
-
patch: makeSseFn("PATCH"),
|
|
2440
|
-
post: makeSseFn("POST"),
|
|
2441
|
-
put: makeSseFn("PUT"),
|
|
2442
|
-
trace: makeSseFn("TRACE")
|
|
2443
|
-
},
|
|
2444
|
-
trace: makeMethodFn("TRACE")
|
|
3217
|
+
const veriOpts = { zip215: true };
|
|
3218
|
+
const _verify = (sig, msg, pub, opts = veriOpts) => {
|
|
3219
|
+
sig = toU8(sig, L2);
|
|
3220
|
+
msg = toU8(msg);
|
|
3221
|
+
pub = toU8(pub, L);
|
|
3222
|
+
const { zip215 } = opts;
|
|
3223
|
+
let A;
|
|
3224
|
+
let R;
|
|
3225
|
+
let s;
|
|
3226
|
+
let SB;
|
|
3227
|
+
let hashable = Uint8Array.of();
|
|
3228
|
+
try {
|
|
3229
|
+
A = Point.fromHex(pub, zip215);
|
|
3230
|
+
R = Point.fromHex(sig.slice(0, L), zip215);
|
|
3231
|
+
s = bytesToNumLE(sig.slice(L, L2));
|
|
3232
|
+
SB = G.multiply(s, false);
|
|
3233
|
+
hashable = concatBytes(R.toBytes(), A.toBytes(), msg);
|
|
3234
|
+
} catch (error) {
|
|
3235
|
+
}
|
|
3236
|
+
const finish = (hashed) => {
|
|
3237
|
+
if (SB == null)
|
|
3238
|
+
return false;
|
|
3239
|
+
if (!zip215 && A.isSmallOrder())
|
|
3240
|
+
return false;
|
|
3241
|
+
const k = modL_LE(hashed);
|
|
3242
|
+
const RkA = R.add(A.multiply(k, false));
|
|
3243
|
+
return RkA.add(SB.negate()).clearCofactor().is0();
|
|
2445
3244
|
};
|
|
3245
|
+
return { hashable, finish };
|
|
2446
3246
|
};
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
)
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
3247
|
+
const verifyAsync = async (s, m, p, opts = veriOpts) => hashFinishA(_verify(s, m, p, opts));
|
|
3248
|
+
const etc = {
|
|
3249
|
+
sha512Async: async (...messages) => {
|
|
3250
|
+
const s = subtle();
|
|
3251
|
+
const m = concatBytes(...messages);
|
|
3252
|
+
return u8n(await s.digest("SHA-512", m.buffer));
|
|
3253
|
+
},
|
|
3254
|
+
sha512Sync: void 0,
|
|
3255
|
+
bytesToHex,
|
|
3256
|
+
hexToBytes,
|
|
3257
|
+
concatBytes,
|
|
3258
|
+
mod: M,
|
|
3259
|
+
invert,
|
|
3260
|
+
randomBytes
|
|
3261
|
+
};
|
|
3262
|
+
const utils = {
|
|
3263
|
+
getExtendedPublicKeyAsync,
|
|
3264
|
+
getExtendedPublicKey,
|
|
3265
|
+
randomPrivateKey: () => randomBytes(L),
|
|
3266
|
+
precompute: (w = 8, p = G) => {
|
|
3267
|
+
p.multiply(3n);
|
|
3268
|
+
return p;
|
|
2460
3269
|
}
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
3270
|
+
// no-op
|
|
3271
|
+
};
|
|
3272
|
+
const W = 8;
|
|
3273
|
+
const scalarBits = 256;
|
|
3274
|
+
const pwindows = Math.ceil(scalarBits / W) + 1;
|
|
3275
|
+
const pwindowSize = 2 ** (W - 1);
|
|
3276
|
+
const precompute = () => {
|
|
3277
|
+
const points = [];
|
|
3278
|
+
let p = G;
|
|
3279
|
+
let b = p;
|
|
3280
|
+
for (let w = 0; w < pwindows; w++) {
|
|
3281
|
+
b = p;
|
|
3282
|
+
points.push(b);
|
|
3283
|
+
for (let i = 1; i < pwindowSize; i++) {
|
|
3284
|
+
b = b.add(p);
|
|
3285
|
+
points.push(b);
|
|
3286
|
+
}
|
|
3287
|
+
p = b.double();
|
|
2477
3288
|
}
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
3289
|
+
return points;
|
|
3290
|
+
};
|
|
3291
|
+
let Gpows = void 0;
|
|
3292
|
+
const ctneg = (cnd, p) => {
|
|
3293
|
+
const n = p.negate();
|
|
3294
|
+
return cnd ? n : p;
|
|
3295
|
+
};
|
|
3296
|
+
const wNAF2 = (n) => {
|
|
3297
|
+
const comp = Gpows || (Gpows = precompute());
|
|
3298
|
+
let p = I;
|
|
3299
|
+
let f = G;
|
|
3300
|
+
const pow_2_w = 2 ** W;
|
|
3301
|
+
const maxNum = pow_2_w;
|
|
3302
|
+
const mask = big(pow_2_w - 1);
|
|
3303
|
+
const shiftBy = big(W);
|
|
3304
|
+
for (let w = 0; w < pwindows; w++) {
|
|
3305
|
+
let wbits = Number(n & mask);
|
|
3306
|
+
n >>= shiftBy;
|
|
3307
|
+
if (wbits > pwindowSize) {
|
|
3308
|
+
wbits -= maxNum;
|
|
3309
|
+
n += 1n;
|
|
3310
|
+
}
|
|
3311
|
+
const off = w * pwindowSize;
|
|
3312
|
+
const offF = off;
|
|
3313
|
+
const offP = off + Math.abs(wbits) - 1;
|
|
3314
|
+
const isEven = w % 2 !== 0;
|
|
3315
|
+
const isNeg = wbits < 0;
|
|
3316
|
+
if (wbits === 0) {
|
|
3317
|
+
f = f.add(ctneg(isEven, comp[offF]));
|
|
3318
|
+
} else {
|
|
3319
|
+
p = p.add(ctneg(isNeg, comp[offP]));
|
|
2483
3320
|
}
|
|
2484
|
-
};
|
|
2485
|
-
await writeFile(filePath, JSON.stringify(merged, null, 2) + "\n");
|
|
2486
|
-
return filePath;
|
|
2487
|
-
}
|
|
2488
|
-
function getConfigDir() {
|
|
2489
|
-
return join(homedir(), ".config", "moltnet");
|
|
2490
|
-
}
|
|
2491
|
-
function getConfigPath(configDir) {
|
|
2492
|
-
return join(configDir ?? getConfigDir(), "moltnet.json");
|
|
2493
|
-
}
|
|
2494
|
-
async function readConfig(configDir) {
|
|
2495
|
-
const dir2 = configDir ?? getConfigDir();
|
|
2496
|
-
try {
|
|
2497
|
-
const content = await readFile(join(dir2, "moltnet.json"), "utf-8");
|
|
2498
|
-
return JSON.parse(content);
|
|
2499
|
-
} catch {
|
|
2500
3321
|
}
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
3322
|
+
return { p, f };
|
|
3323
|
+
};
|
|
3324
|
+
etc.sha512Sync = (...m) => {
|
|
3325
|
+
const hash = createHash("sha512");
|
|
3326
|
+
m.forEach((msg) => hash.update(msg));
|
|
3327
|
+
return hash.digest();
|
|
3328
|
+
};
|
|
3329
|
+
const DOMAIN_PREFIX = "moltnet:v1";
|
|
3330
|
+
function buildSigningBytes(message, nonce) {
|
|
3331
|
+
const msgHash = createHash("sha256").update(Buffer.from(message, "utf-8")).digest();
|
|
3332
|
+
const nonceBytes = Buffer.from(nonce, "utf-8");
|
|
3333
|
+
const prefix = Buffer.from(DOMAIN_PREFIX, "utf-8");
|
|
3334
|
+
const buf = Buffer.alloc(
|
|
3335
|
+
prefix.length + 4 + msgHash.length + 4 + nonceBytes.length
|
|
3336
|
+
);
|
|
3337
|
+
let offset = 0;
|
|
3338
|
+
prefix.copy(buf, offset);
|
|
3339
|
+
offset += prefix.length;
|
|
3340
|
+
buf.writeUInt32BE(msgHash.length, offset);
|
|
3341
|
+
offset += 4;
|
|
3342
|
+
msgHash.copy(buf, offset);
|
|
3343
|
+
offset += msgHash.length;
|
|
3344
|
+
buf.writeUInt32BE(nonceBytes.length, offset);
|
|
3345
|
+
offset += 4;
|
|
3346
|
+
nonceBytes.copy(buf, offset);
|
|
3347
|
+
return new Uint8Array(buf);
|
|
3348
|
+
}
|
|
3349
|
+
const cryptoService = {
|
|
3350
|
+
/**
|
|
3351
|
+
* Generate a new Ed25519 keypair
|
|
3352
|
+
*/
|
|
3353
|
+
async generateKeyPair() {
|
|
3354
|
+
const privateKeyBytes = utils.randomPrivateKey();
|
|
3355
|
+
const publicKeyBytes = await getPublicKeyAsync(privateKeyBytes);
|
|
3356
|
+
const privateKey = Buffer.from(privateKeyBytes).toString("base64");
|
|
3357
|
+
const publicKey = `ed25519:${Buffer.from(publicKeyBytes).toString("base64")}`;
|
|
3358
|
+
const fingerprint = this.generateFingerprint(publicKeyBytes);
|
|
3359
|
+
return { publicKey, privateKey, fingerprint };
|
|
3360
|
+
},
|
|
3361
|
+
/**
|
|
3362
|
+
* Generate human-readable fingerprint from public key
|
|
3363
|
+
* Format: A1B2-C3D4-E5F6-G7H8 (first 16 hex chars of SHA256)
|
|
3364
|
+
*/
|
|
3365
|
+
generateFingerprint(publicKeyBytes) {
|
|
3366
|
+
const hash = createHash("sha256").update(publicKeyBytes).digest("hex");
|
|
3367
|
+
const segments = hash.slice(0, 16).toUpperCase().match(/.{4}/g) ?? [];
|
|
3368
|
+
return segments.join("-");
|
|
3369
|
+
},
|
|
3370
|
+
/**
|
|
3371
|
+
* Parse public key from string format
|
|
3372
|
+
*/
|
|
3373
|
+
parsePublicKey(publicKey) {
|
|
3374
|
+
const base64 = publicKey.replace(/^ed25519:/, "");
|
|
3375
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
3376
|
+
},
|
|
3377
|
+
/**
|
|
3378
|
+
* Sign a message with private key
|
|
3379
|
+
*/
|
|
3380
|
+
async sign(message, privateKeyBase64) {
|
|
3381
|
+
const privateKeyBytes = new Uint8Array(
|
|
3382
|
+
Buffer.from(privateKeyBase64, "base64")
|
|
3383
|
+
);
|
|
3384
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
3385
|
+
const signature = await signAsync(messageBytes, privateKeyBytes);
|
|
3386
|
+
return Buffer.from(signature).toString("base64");
|
|
3387
|
+
},
|
|
3388
|
+
/**
|
|
3389
|
+
* Verify a signature against a message and public key
|
|
3390
|
+
*/
|
|
3391
|
+
async verify(message, signature, publicKey) {
|
|
3392
|
+
try {
|
|
3393
|
+
const publicKeyBytes = this.parsePublicKey(publicKey);
|
|
3394
|
+
const signatureBytes = new Uint8Array(Buffer.from(signature, "base64"));
|
|
3395
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
3396
|
+
return await verifyAsync(signatureBytes, messageBytes, publicKeyBytes);
|
|
3397
|
+
} catch {
|
|
3398
|
+
return false;
|
|
3399
|
+
}
|
|
3400
|
+
},
|
|
3401
|
+
/**
|
|
3402
|
+
* Sign a (message, nonce) pair using deterministic pre-hash.
|
|
3403
|
+
* Uses buildSigningBytes for domain separation and canonical serialization.
|
|
3404
|
+
*/
|
|
3405
|
+
async signWithNonce(message, nonce, privateKeyBase64) {
|
|
3406
|
+
const privateKeyBytes = new Uint8Array(
|
|
3407
|
+
Buffer.from(privateKeyBase64, "base64")
|
|
3408
|
+
);
|
|
3409
|
+
const signingBytes = buildSigningBytes(message, nonce);
|
|
3410
|
+
const signature = await signAsync(signingBytes, privateKeyBytes);
|
|
3411
|
+
return Buffer.from(signature).toString("base64");
|
|
3412
|
+
},
|
|
3413
|
+
/**
|
|
3414
|
+
* Verify a signature produced by signWithNonce.
|
|
3415
|
+
*/
|
|
3416
|
+
async verifyWithNonce(message, nonce, signature, publicKey) {
|
|
3417
|
+
try {
|
|
3418
|
+
const publicKeyBytes = this.parsePublicKey(publicKey);
|
|
3419
|
+
const signatureBytes = new Uint8Array(Buffer.from(signature, "base64"));
|
|
3420
|
+
const signingBytes = buildSigningBytes(message, nonce);
|
|
3421
|
+
return await verifyAsync(signatureBytes, signingBytes, publicKeyBytes);
|
|
3422
|
+
} catch {
|
|
3423
|
+
return false;
|
|
3424
|
+
}
|
|
3425
|
+
},
|
|
3426
|
+
/**
|
|
3427
|
+
* Create a signed message object
|
|
3428
|
+
*/
|
|
3429
|
+
async createSignedMessage(message, privateKeyBase64, publicKey) {
|
|
3430
|
+
const signature = await this.sign(message, privateKeyBase64);
|
|
3431
|
+
return { message, signature, publicKey };
|
|
3432
|
+
},
|
|
3433
|
+
/**
|
|
3434
|
+
* Verify a signed message object
|
|
3435
|
+
*/
|
|
3436
|
+
async verifySignedMessage(signedMessage) {
|
|
3437
|
+
return this.verify(
|
|
3438
|
+
signedMessage.message,
|
|
3439
|
+
signedMessage.signature,
|
|
3440
|
+
signedMessage.publicKey
|
|
3441
|
+
);
|
|
3442
|
+
},
|
|
3443
|
+
/**
|
|
3444
|
+
* Generate a random challenge for authentication
|
|
3445
|
+
*/
|
|
3446
|
+
generateChallenge() {
|
|
3447
|
+
return `moltnet:challenge:${randomBytes$2(32).toString("hex")}:${Date.now()}`;
|
|
3448
|
+
},
|
|
3449
|
+
/**
|
|
3450
|
+
* Derive public key from private key
|
|
3451
|
+
*/
|
|
3452
|
+
async derivePublicKey(privateKeyBase64) {
|
|
3453
|
+
const privateKeyBytes = new Uint8Array(
|
|
3454
|
+
Buffer.from(privateKeyBase64, "base64")
|
|
2505
3455
|
);
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
3456
|
+
const publicKeyBytes = await getPublicKeyAsync(privateKeyBytes);
|
|
3457
|
+
return `ed25519:${Buffer.from(publicKeyBytes).toString("base64")}`;
|
|
3458
|
+
},
|
|
3459
|
+
/**
|
|
3460
|
+
* Get fingerprint from public key string
|
|
3461
|
+
*/
|
|
3462
|
+
getFingerprintFromPublicKey(publicKey) {
|
|
3463
|
+
const publicKeyBytes = this.parsePublicKey(publicKey);
|
|
3464
|
+
return this.generateFingerprint(publicKeyBytes);
|
|
3465
|
+
},
|
|
3466
|
+
/**
|
|
3467
|
+
* Derive an X25519 private key from an Ed25519 private key seed.
|
|
3468
|
+
* Uses SHA-512 expansion + clamping per RFC 7748 / RFC 8032.
|
|
3469
|
+
*/
|
|
3470
|
+
deriveX25519PrivateKey(ed25519PrivateKeyBase64) {
|
|
3471
|
+
const seed = new Uint8Array(Buffer.from(ed25519PrivateKeyBase64, "base64"));
|
|
3472
|
+
const x25519Priv = ed25519.utils.toMontgomerySecret(seed);
|
|
3473
|
+
return Buffer.from(x25519Priv).toString("base64");
|
|
3474
|
+
},
|
|
3475
|
+
/**
|
|
3476
|
+
* Derive an X25519 public key from an Ed25519 public key.
|
|
3477
|
+
* Uses the Edwards → Montgomery birational map.
|
|
3478
|
+
*/
|
|
3479
|
+
deriveX25519PublicKey(ed25519PublicKey) {
|
|
3480
|
+
const edPubBytes = this.parsePublicKey(ed25519PublicKey);
|
|
3481
|
+
const x25519Pub = ed25519.utils.toMontgomery(edPubBytes);
|
|
3482
|
+
return `x25519:${Buffer.from(x25519Pub).toString("base64")}`;
|
|
3483
|
+
},
|
|
3484
|
+
/**
|
|
3485
|
+
* Create a proof of identity ownership (for DCR metadata)
|
|
3486
|
+
*/
|
|
3487
|
+
async createIdentityProof(identityId, privateKeyBase64) {
|
|
3488
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3489
|
+
const message = `moltnet:register:${identityId}:${timestamp}`;
|
|
3490
|
+
const signature = await this.sign(message, privateKeyBase64);
|
|
3491
|
+
return { message, signature, timestamp };
|
|
3492
|
+
},
|
|
3493
|
+
/**
|
|
3494
|
+
* Verify an identity proof
|
|
3495
|
+
*/
|
|
3496
|
+
async verifyIdentityProof(proof, publicKey, expectedIdentityId) {
|
|
3497
|
+
const isValid = await this.verify(
|
|
3498
|
+
proof.message,
|
|
3499
|
+
proof.signature,
|
|
3500
|
+
publicKey
|
|
3501
|
+
);
|
|
3502
|
+
if (!isValid) return false;
|
|
3503
|
+
const expectedPrefix = `moltnet:register:${expectedIdentityId}:`;
|
|
3504
|
+
if (!proof.message.startsWith(expectedPrefix)) return false;
|
|
3505
|
+
const proofTime = new Date(proof.timestamp).getTime();
|
|
3506
|
+
const now = Date.now();
|
|
3507
|
+
const fiveMinutes = 5 * 60 * 1e3;
|
|
3508
|
+
if (now - proofTime > fiveMinutes) return false;
|
|
3509
|
+
return true;
|
|
2525
3510
|
}
|
|
2526
|
-
const existing = config[section] ?? {};
|
|
2527
|
-
const updated = { ...existing, ...data };
|
|
2528
|
-
Object.assign(config, { [section]: updated });
|
|
2529
|
-
await writeConfig(config, configDir);
|
|
2530
|
-
}
|
|
2531
|
-
etc.sha512Sync = (...m) => {
|
|
2532
|
-
const hash = createHash("sha512");
|
|
2533
|
-
m.forEach((msg) => hash.update(msg));
|
|
2534
|
-
return hash.digest();
|
|
2535
3511
|
};
|
|
2536
3512
|
if (!etc.sha512Sync) {
|
|
2537
3513
|
etc.sha512Sync = (...m) => {
|
|
@@ -2637,25 +3613,19 @@ function toSSHPrivateKey(seedBase64) {
|
|
|
2637
3613
|
].join("\n");
|
|
2638
3614
|
}
|
|
2639
3615
|
async function exportSSHKey(opts) {
|
|
2640
|
-
const config = await readConfig(opts
|
|
3616
|
+
const config = await readConfig(opts?.configDir);
|
|
2641
3617
|
if (!config) {
|
|
2642
|
-
throw new Error(
|
|
2643
|
-
`No config found at ${getConfigPath(opts == null ? void 0 : opts.configDir)} — run \`moltnet register\` first`
|
|
2644
|
-
);
|
|
3618
|
+
throw new Error(`No config found at ${getConfigPath(opts?.configDir)} — run \`moltnet register\` first`);
|
|
2645
3619
|
}
|
|
2646
3620
|
const privateKeySSH = toSSHPrivateKey(config.keys.private_key);
|
|
2647
3621
|
const publicKeySSH = toSSHPublicKey(config.keys.public_key);
|
|
2648
|
-
const outputDir =
|
|
3622
|
+
const outputDir = opts?.outputDir ?? join(opts?.configDir ?? getConfigDir(), "ssh");
|
|
2649
3623
|
await mkdir(outputDir, { recursive: true });
|
|
2650
3624
|
const privatePath = join(outputDir, "id_ed25519");
|
|
2651
3625
|
const publicPath = join(outputDir, "id_ed25519.pub");
|
|
2652
3626
|
await writeFile(privatePath, privateKeySSH, { mode: 384 });
|
|
2653
3627
|
await writeFile(publicPath, publicKeySSH, { mode: 420 });
|
|
2654
|
-
await updateConfigSection(
|
|
2655
|
-
"ssh",
|
|
2656
|
-
{ private_key_path: privatePath, public_key_path: publicPath },
|
|
2657
|
-
opts == null ? void 0 : opts.configDir
|
|
2658
|
-
);
|
|
3628
|
+
await updateConfigSection("ssh", { private_key_path: privatePath, public_key_path: publicPath }, opts?.configDir);
|
|
2659
3629
|
return { privatePath, publicPath };
|
|
2660
3630
|
}
|
|
2661
3631
|
const POLL_INTERVAL_MS = 5e3;
|
|
@@ -2673,7 +3643,7 @@ function toErrorMessage(err2) {
|
|
|
2673
3643
|
}
|
|
2674
3644
|
const POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
2675
3645
|
function makeClient(baseUrl) {
|
|
2676
|
-
return createClient
|
|
3646
|
+
return createClient({ baseUrl });
|
|
2677
3647
|
}
|
|
2678
3648
|
async function startOnboarding(baseUrl, body) {
|
|
2679
3649
|
const client2 = makeClient(baseUrl);
|
|
@@ -3216,183 +4186,6 @@ async function runGitSetupPhase(opts) {
|
|
|
3216
4186
|
);
|
|
3217
4187
|
dispatch({ type: "step", key: "gitSetup", status: "done" });
|
|
3218
4188
|
}
|
|
3219
|
-
etc.sha512Sync = (...m) => {
|
|
3220
|
-
const hash = createHash("sha512");
|
|
3221
|
-
m.forEach((msg) => hash.update(msg));
|
|
3222
|
-
return hash.digest();
|
|
3223
|
-
};
|
|
3224
|
-
const DOMAIN_PREFIX = "moltnet:v1";
|
|
3225
|
-
function buildSigningBytes(message, nonce) {
|
|
3226
|
-
const msgHash = createHash("sha256").update(Buffer.from(message, "utf-8")).digest();
|
|
3227
|
-
const nonceBytes = Buffer.from(nonce, "utf-8");
|
|
3228
|
-
const prefix = Buffer.from(DOMAIN_PREFIX, "utf-8");
|
|
3229
|
-
const buf = Buffer.alloc(
|
|
3230
|
-
prefix.length + 4 + msgHash.length + 4 + nonceBytes.length
|
|
3231
|
-
);
|
|
3232
|
-
let offset = 0;
|
|
3233
|
-
prefix.copy(buf, offset);
|
|
3234
|
-
offset += prefix.length;
|
|
3235
|
-
buf.writeUInt32BE(msgHash.length, offset);
|
|
3236
|
-
offset += 4;
|
|
3237
|
-
msgHash.copy(buf, offset);
|
|
3238
|
-
offset += msgHash.length;
|
|
3239
|
-
buf.writeUInt32BE(nonceBytes.length, offset);
|
|
3240
|
-
offset += 4;
|
|
3241
|
-
nonceBytes.copy(buf, offset);
|
|
3242
|
-
return new Uint8Array(buf);
|
|
3243
|
-
}
|
|
3244
|
-
const cryptoService = {
|
|
3245
|
-
/**
|
|
3246
|
-
* Generate a new Ed25519 keypair
|
|
3247
|
-
*/
|
|
3248
|
-
async generateKeyPair() {
|
|
3249
|
-
const privateKeyBytes = utils.randomPrivateKey();
|
|
3250
|
-
const publicKeyBytes = await getPublicKeyAsync(privateKeyBytes);
|
|
3251
|
-
const privateKey = Buffer.from(privateKeyBytes).toString("base64");
|
|
3252
|
-
const publicKey = `ed25519:${Buffer.from(publicKeyBytes).toString("base64")}`;
|
|
3253
|
-
const fingerprint = this.generateFingerprint(publicKeyBytes);
|
|
3254
|
-
return { publicKey, privateKey, fingerprint };
|
|
3255
|
-
},
|
|
3256
|
-
/**
|
|
3257
|
-
* Generate human-readable fingerprint from public key
|
|
3258
|
-
* Format: A1B2-C3D4-E5F6-G7H8 (first 16 hex chars of SHA256)
|
|
3259
|
-
*/
|
|
3260
|
-
generateFingerprint(publicKeyBytes) {
|
|
3261
|
-
const hash = createHash("sha256").update(publicKeyBytes).digest("hex");
|
|
3262
|
-
const segments = hash.slice(0, 16).toUpperCase().match(/.{4}/g) ?? [];
|
|
3263
|
-
return segments.join("-");
|
|
3264
|
-
},
|
|
3265
|
-
/**
|
|
3266
|
-
* Parse public key from string format
|
|
3267
|
-
*/
|
|
3268
|
-
parsePublicKey(publicKey) {
|
|
3269
|
-
const base64 = publicKey.replace(/^ed25519:/, "");
|
|
3270
|
-
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
3271
|
-
},
|
|
3272
|
-
/**
|
|
3273
|
-
* Sign a message with private key
|
|
3274
|
-
*/
|
|
3275
|
-
async sign(message, privateKeyBase64) {
|
|
3276
|
-
const privateKeyBytes = new Uint8Array(
|
|
3277
|
-
Buffer.from(privateKeyBase64, "base64")
|
|
3278
|
-
);
|
|
3279
|
-
const messageBytes = new TextEncoder().encode(message);
|
|
3280
|
-
const signature = await signAsync(messageBytes, privateKeyBytes);
|
|
3281
|
-
return Buffer.from(signature).toString("base64");
|
|
3282
|
-
},
|
|
3283
|
-
/**
|
|
3284
|
-
* Verify a signature against a message and public key
|
|
3285
|
-
*/
|
|
3286
|
-
async verify(message, signature, publicKey) {
|
|
3287
|
-
try {
|
|
3288
|
-
const publicKeyBytes = this.parsePublicKey(publicKey);
|
|
3289
|
-
const signatureBytes = new Uint8Array(Buffer.from(signature, "base64"));
|
|
3290
|
-
const messageBytes = new TextEncoder().encode(message);
|
|
3291
|
-
return await verifyAsync(signatureBytes, messageBytes, publicKeyBytes);
|
|
3292
|
-
} catch {
|
|
3293
|
-
return false;
|
|
3294
|
-
}
|
|
3295
|
-
},
|
|
3296
|
-
/**
|
|
3297
|
-
* Sign a (message, nonce) pair using deterministic pre-hash.
|
|
3298
|
-
* Uses buildSigningBytes for domain separation and canonical serialization.
|
|
3299
|
-
*/
|
|
3300
|
-
async signWithNonce(message, nonce, privateKeyBase64) {
|
|
3301
|
-
const privateKeyBytes = new Uint8Array(
|
|
3302
|
-
Buffer.from(privateKeyBase64, "base64")
|
|
3303
|
-
);
|
|
3304
|
-
const signingBytes = buildSigningBytes(message, nonce);
|
|
3305
|
-
const signature = await signAsync(signingBytes, privateKeyBytes);
|
|
3306
|
-
return Buffer.from(signature).toString("base64");
|
|
3307
|
-
},
|
|
3308
|
-
/**
|
|
3309
|
-
* Verify a signature produced by signWithNonce.
|
|
3310
|
-
*/
|
|
3311
|
-
async verifyWithNonce(message, nonce, signature, publicKey) {
|
|
3312
|
-
try {
|
|
3313
|
-
const publicKeyBytes = this.parsePublicKey(publicKey);
|
|
3314
|
-
const signatureBytes = new Uint8Array(Buffer.from(signature, "base64"));
|
|
3315
|
-
const signingBytes = buildSigningBytes(message, nonce);
|
|
3316
|
-
return await verifyAsync(signatureBytes, signingBytes, publicKeyBytes);
|
|
3317
|
-
} catch {
|
|
3318
|
-
return false;
|
|
3319
|
-
}
|
|
3320
|
-
},
|
|
3321
|
-
/**
|
|
3322
|
-
* Create a signed message object
|
|
3323
|
-
*/
|
|
3324
|
-
async createSignedMessage(message, privateKeyBase64, publicKey) {
|
|
3325
|
-
const signature = await this.sign(message, privateKeyBase64);
|
|
3326
|
-
return { message, signature, publicKey };
|
|
3327
|
-
},
|
|
3328
|
-
/**
|
|
3329
|
-
* Verify a signed message object
|
|
3330
|
-
*/
|
|
3331
|
-
async verifySignedMessage(signedMessage) {
|
|
3332
|
-
return this.verify(
|
|
3333
|
-
signedMessage.message,
|
|
3334
|
-
signedMessage.signature,
|
|
3335
|
-
signedMessage.publicKey
|
|
3336
|
-
);
|
|
3337
|
-
},
|
|
3338
|
-
/**
|
|
3339
|
-
* Generate a random challenge for authentication
|
|
3340
|
-
*/
|
|
3341
|
-
generateChallenge() {
|
|
3342
|
-
return `moltnet:challenge:${randomBytes$1(32).toString("hex")}:${Date.now()}`;
|
|
3343
|
-
},
|
|
3344
|
-
/**
|
|
3345
|
-
* Derive public key from private key
|
|
3346
|
-
*/
|
|
3347
|
-
async derivePublicKey(privateKeyBase64) {
|
|
3348
|
-
const privateKeyBytes = new Uint8Array(
|
|
3349
|
-
Buffer.from(privateKeyBase64, "base64")
|
|
3350
|
-
);
|
|
3351
|
-
const publicKeyBytes = await getPublicKeyAsync(privateKeyBytes);
|
|
3352
|
-
return `ed25519:${Buffer.from(publicKeyBytes).toString("base64")}`;
|
|
3353
|
-
},
|
|
3354
|
-
/**
|
|
3355
|
-
* Get fingerprint from public key string
|
|
3356
|
-
*/
|
|
3357
|
-
getFingerprintFromPublicKey(publicKey) {
|
|
3358
|
-
const publicKeyBytes = this.parsePublicKey(publicKey);
|
|
3359
|
-
return this.generateFingerprint(publicKeyBytes);
|
|
3360
|
-
},
|
|
3361
|
-
/**
|
|
3362
|
-
* Create a proof of identity ownership (for DCR metadata)
|
|
3363
|
-
*/
|
|
3364
|
-
async createIdentityProof(identityId, privateKeyBase64) {
|
|
3365
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
3366
|
-
const message = `moltnet:register:${identityId}:${timestamp}`;
|
|
3367
|
-
const signature = await this.sign(message, privateKeyBase64);
|
|
3368
|
-
return { message, signature, timestamp };
|
|
3369
|
-
},
|
|
3370
|
-
/**
|
|
3371
|
-
* Verify an identity proof
|
|
3372
|
-
*/
|
|
3373
|
-
async verifyIdentityProof(proof, publicKey, expectedIdentityId) {
|
|
3374
|
-
const isValid = await this.verify(
|
|
3375
|
-
proof.message,
|
|
3376
|
-
proof.signature,
|
|
3377
|
-
publicKey
|
|
3378
|
-
);
|
|
3379
|
-
if (!isValid) return false;
|
|
3380
|
-
const expectedPrefix = `moltnet:register:${expectedIdentityId}:`;
|
|
3381
|
-
if (!proof.message.startsWith(expectedPrefix)) return false;
|
|
3382
|
-
const proofTime = new Date(proof.timestamp).getTime();
|
|
3383
|
-
const now = Date.now();
|
|
3384
|
-
const fiveMinutes = 5 * 60 * 1e3;
|
|
3385
|
-
if (now - proofTime > fiveMinutes) return false;
|
|
3386
|
-
return true;
|
|
3387
|
-
}
|
|
3388
|
-
};
|
|
3389
|
-
if (!etc.sha512Sync) {
|
|
3390
|
-
etc.sha512Sync = (...m) => {
|
|
3391
|
-
const hash = createHash("sha512");
|
|
3392
|
-
m.forEach((msg) => hash.update(msg));
|
|
3393
|
-
return hash.digest();
|
|
3394
|
-
};
|
|
3395
|
-
}
|
|
3396
4189
|
async function runIdentityPhase(opts) {
|
|
3397
4190
|
const { apiUrl: apiUrl2, agentName, configDir, dispatch } = opts;
|
|
3398
4191
|
const existingConfig = await readConfig(configDir);
|