@motebit/crypto 0.8.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +198 -18
- package/NOTICE +19 -0
- package/README.md +11 -3
- package/dist/artifacts.d.ts +431 -32
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +694 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/credential-anchor.d.ts +76 -2
- package/dist/credential-anchor.d.ts.map +1 -1
- package/dist/credential-anchor.js +109 -22
- package/dist/credential-anchor.js.map +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/credentials.js +1 -1
- package/dist/hardware-attestation.d.ts +238 -0
- package/dist/hardware-attestation.d.ts.map +1 -0
- package/dist/hardware-attestation.js +345 -0
- package/dist/hardware-attestation.js.map +1 -0
- package/dist/index.d.ts +56 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3322 -288
- package/dist/index.js.map +1 -1
- package/dist/signing.d.ts +52 -17
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +67 -35
- package/dist/signing.js.map +1 -1
- package/dist/suite-dispatch.d.ts +103 -0
- package/dist/suite-dispatch.d.ts.map +1 -0
- package/dist/suite-dispatch.js +3233 -0
- package/dist/suite-dispatch.js.map +1 -0
- package/package.json +20 -5
package/dist/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
1
7
|
// ../../node_modules/.pnpm/@noble+ed25519@3.0.1/node_modules/@noble/ed25519/index.js
|
|
2
8
|
var ed25519_CURVE = {
|
|
3
9
|
p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
|
|
@@ -339,8 +345,8 @@ var RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n;
|
|
|
339
345
|
var uvRatio = (u, v) => {
|
|
340
346
|
const v3 = modP(v * modP(v * v));
|
|
341
347
|
const v7 = modP(modP(v3 * v3) * v);
|
|
342
|
-
const
|
|
343
|
-
let x = modP(u * modP(v3 *
|
|
348
|
+
const pow3 = pow_2_252_3(modP(u * v7)).pow_p_5_8;
|
|
349
|
+
let x = modP(u * modP(v3 * pow3));
|
|
344
350
|
const vx2 = modP(v * modP(x * x));
|
|
345
351
|
const root1 = x;
|
|
346
352
|
const root2 = modP(x * RM1);
|
|
@@ -514,6 +520,7 @@ function aoutput(out, instance) {
|
|
|
514
520
|
|
|
515
521
|
// ../../node_modules/.pnpm/@noble+hashes@1.6.1/node_modules/@noble/hashes/esm/utils.js
|
|
516
522
|
var createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
523
|
+
var rotr = (word, shift) => word << 32 - shift | word >>> shift;
|
|
517
524
|
function utf8ToBytes(str) {
|
|
518
525
|
if (typeof str !== "string")
|
|
519
526
|
throw new Error("utf8ToBytes expected string, got " + typeof str);
|
|
@@ -553,6 +560,8 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
|
553
560
|
view.setUint32(byteOffset + h2, wh, isLE);
|
|
554
561
|
view.setUint32(byteOffset + l, wl, isLE);
|
|
555
562
|
}
|
|
563
|
+
var Chi = (a, b, c) => a & b ^ ~a & c;
|
|
564
|
+
var Maj = (a, b, c) => a & b ^ a & c ^ b & c;
|
|
556
565
|
var HashMD = class extends Hash {
|
|
557
566
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
558
567
|
super();
|
|
@@ -905,207 +914,2815 @@ var SHA512 = class extends HashMD {
|
|
|
905
914
|
};
|
|
906
915
|
var sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
|
907
916
|
|
|
908
|
-
//
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
917
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.1/node_modules/@noble/hashes/esm/sha256.js
|
|
918
|
+
var SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
919
|
+
1116352408,
|
|
920
|
+
1899447441,
|
|
921
|
+
3049323471,
|
|
922
|
+
3921009573,
|
|
923
|
+
961987163,
|
|
924
|
+
1508970993,
|
|
925
|
+
2453635748,
|
|
926
|
+
2870763221,
|
|
927
|
+
3624381080,
|
|
928
|
+
310598401,
|
|
929
|
+
607225278,
|
|
930
|
+
1426881987,
|
|
931
|
+
1925078388,
|
|
932
|
+
2162078206,
|
|
933
|
+
2614888103,
|
|
934
|
+
3248222580,
|
|
935
|
+
3835390401,
|
|
936
|
+
4022224774,
|
|
937
|
+
264347078,
|
|
938
|
+
604807628,
|
|
939
|
+
770255983,
|
|
940
|
+
1249150122,
|
|
941
|
+
1555081692,
|
|
942
|
+
1996064986,
|
|
943
|
+
2554220882,
|
|
944
|
+
2821834349,
|
|
945
|
+
2952996808,
|
|
946
|
+
3210313671,
|
|
947
|
+
3336571891,
|
|
948
|
+
3584528711,
|
|
949
|
+
113926993,
|
|
950
|
+
338241895,
|
|
951
|
+
666307205,
|
|
952
|
+
773529912,
|
|
953
|
+
1294757372,
|
|
954
|
+
1396182291,
|
|
955
|
+
1695183700,
|
|
956
|
+
1986661051,
|
|
957
|
+
2177026350,
|
|
958
|
+
2456956037,
|
|
959
|
+
2730485921,
|
|
960
|
+
2820302411,
|
|
961
|
+
3259730800,
|
|
962
|
+
3345764771,
|
|
963
|
+
3516065817,
|
|
964
|
+
3600352804,
|
|
965
|
+
4094571909,
|
|
966
|
+
275423344,
|
|
967
|
+
430227734,
|
|
968
|
+
506948616,
|
|
969
|
+
659060556,
|
|
970
|
+
883997877,
|
|
971
|
+
958139571,
|
|
972
|
+
1322822218,
|
|
973
|
+
1537002063,
|
|
974
|
+
1747873779,
|
|
975
|
+
1955562222,
|
|
976
|
+
2024104815,
|
|
977
|
+
2227730452,
|
|
978
|
+
2361852424,
|
|
979
|
+
2428436474,
|
|
980
|
+
2756734187,
|
|
981
|
+
3204031479,
|
|
982
|
+
3329325298
|
|
983
|
+
]);
|
|
984
|
+
var SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
|
985
|
+
1779033703,
|
|
986
|
+
3144134277,
|
|
987
|
+
1013904242,
|
|
988
|
+
2773480762,
|
|
989
|
+
1359893119,
|
|
990
|
+
2600822924,
|
|
991
|
+
528734635,
|
|
992
|
+
1541459225
|
|
993
|
+
]);
|
|
994
|
+
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
995
|
+
var SHA256 = class extends HashMD {
|
|
996
|
+
constructor() {
|
|
997
|
+
super(64, 32, 8, false);
|
|
998
|
+
this.A = SHA256_IV[0] | 0;
|
|
999
|
+
this.B = SHA256_IV[1] | 0;
|
|
1000
|
+
this.C = SHA256_IV[2] | 0;
|
|
1001
|
+
this.D = SHA256_IV[3] | 0;
|
|
1002
|
+
this.E = SHA256_IV[4] | 0;
|
|
1003
|
+
this.F = SHA256_IV[5] | 0;
|
|
1004
|
+
this.G = SHA256_IV[6] | 0;
|
|
1005
|
+
this.H = SHA256_IV[7] | 0;
|
|
941
1006
|
}
|
|
942
|
-
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
const padded = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
946
|
-
const binary = atob(padded);
|
|
947
|
-
const bytes = new Uint8Array(binary.length);
|
|
948
|
-
for (let i = 0; i < binary.length; i++) {
|
|
949
|
-
bytes[i] = binary.charCodeAt(i);
|
|
1007
|
+
get() {
|
|
1008
|
+
const { A, B, C: C2, D, E, F, G: G2, H } = this;
|
|
1009
|
+
return [A, B, C2, D, E, F, G2, H];
|
|
950
1010
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1011
|
+
// prettier-ignore
|
|
1012
|
+
set(A, B, C2, D, E, F, G2, H) {
|
|
1013
|
+
this.A = A | 0;
|
|
1014
|
+
this.B = B | 0;
|
|
1015
|
+
this.C = C2 | 0;
|
|
1016
|
+
this.D = D | 0;
|
|
1017
|
+
this.E = E | 0;
|
|
1018
|
+
this.F = F | 0;
|
|
1019
|
+
this.G = G2 | 0;
|
|
1020
|
+
this.H = H | 0;
|
|
960
1021
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
1022
|
+
process(view, offset) {
|
|
1023
|
+
for (let i = 0; i < 16; i++, offset += 4)
|
|
1024
|
+
SHA256_W[i] = view.getUint32(offset, false);
|
|
1025
|
+
for (let i = 16; i < 64; i++) {
|
|
1026
|
+
const W15 = SHA256_W[i - 15];
|
|
1027
|
+
const W2 = SHA256_W[i - 2];
|
|
1028
|
+
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
1029
|
+
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
1030
|
+
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
1031
|
+
}
|
|
1032
|
+
let { A, B, C: C2, D, E, F, G: G2, H } = this;
|
|
1033
|
+
for (let i = 0; i < 64; i++) {
|
|
1034
|
+
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
1035
|
+
const T1 = H + sigma1 + Chi(E, F, G2) + SHA256_K[i] + SHA256_W[i] | 0;
|
|
1036
|
+
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
1037
|
+
const T2 = sigma0 + Maj(A, B, C2) | 0;
|
|
1038
|
+
H = G2;
|
|
1039
|
+
G2 = F;
|
|
1040
|
+
F = E;
|
|
1041
|
+
E = D + T1 | 0;
|
|
1042
|
+
D = C2;
|
|
1043
|
+
C2 = B;
|
|
1044
|
+
B = A;
|
|
1045
|
+
A = T1 + T2 | 0;
|
|
1046
|
+
}
|
|
1047
|
+
A = A + this.A | 0;
|
|
1048
|
+
B = B + this.B | 0;
|
|
1049
|
+
C2 = C2 + this.C | 0;
|
|
1050
|
+
D = D + this.D | 0;
|
|
1051
|
+
E = E + this.E | 0;
|
|
1052
|
+
F = F + this.F | 0;
|
|
1053
|
+
G2 = G2 + this.G | 0;
|
|
1054
|
+
H = H + this.H | 0;
|
|
1055
|
+
this.set(A, B, C2, D, E, F, G2, H);
|
|
966
1056
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
function base58btcDecode(str) {
|
|
970
|
-
let zeros = 0;
|
|
971
|
-
while (zeros < str.length && str[zeros] === BASE58_ALPHABET[0]) zeros++;
|
|
972
|
-
let value = 0n;
|
|
973
|
-
for (let i = 0; i < str.length; i++) {
|
|
974
|
-
const idx = BASE58_ALPHABET.indexOf(str[i]);
|
|
975
|
-
if (idx === -1) throw new Error(`Invalid base58 character: ${str[i]}`);
|
|
976
|
-
value = value * 58n + BigInt(idx);
|
|
1057
|
+
roundClean() {
|
|
1058
|
+
SHA256_W.fill(0);
|
|
977
1059
|
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
hex.unshift(byte.toString(16).padStart(2, "0"));
|
|
982
|
-
value >>= 8n;
|
|
1060
|
+
destroy() {
|
|
1061
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
1062
|
+
this.buffer.fill(0);
|
|
983
1063
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1064
|
+
};
|
|
1065
|
+
var sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
|
1066
|
+
|
|
1067
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.0/node_modules/@noble/hashes/esm/_assert.js
|
|
1068
|
+
function anumber(n) {
|
|
1069
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
1070
|
+
throw new Error("positive integer expected, got " + n);
|
|
988
1071
|
}
|
|
989
|
-
function
|
|
990
|
-
|
|
991
|
-
throw new Error("Invalid did:key URI: must start with did:key:z");
|
|
992
|
-
}
|
|
993
|
-
const encoded = did.slice("did:key:z".length);
|
|
994
|
-
const decoded = base58btcDecode(encoded);
|
|
995
|
-
if (decoded.length !== 34) {
|
|
996
|
-
throw new Error(
|
|
997
|
-
`Invalid did:key: expected 34 bytes (2 prefix + 32 key), got ${decoded.length}`
|
|
998
|
-
);
|
|
999
|
-
}
|
|
1000
|
-
if (decoded[0] !== 237 || decoded[1] !== 1) {
|
|
1001
|
-
throw new Error("Invalid did:key: multicodec prefix is not ed25519-pub (0xed01)");
|
|
1002
|
-
}
|
|
1003
|
-
return decoded.slice(2);
|
|
1072
|
+
function isBytes3(a) {
|
|
1073
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
1004
1074
|
}
|
|
1005
|
-
function
|
|
1006
|
-
if (
|
|
1007
|
-
throw new Error("
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
prefixed[0] = 237;
|
|
1011
|
-
prefixed[1] = 1;
|
|
1012
|
-
prefixed.set(publicKey, 2);
|
|
1013
|
-
return `did:key:z${base58btcEncode(prefixed)}`;
|
|
1075
|
+
function abytes3(b, ...lengths) {
|
|
1076
|
+
if (!isBytes3(b))
|
|
1077
|
+
throw new Error("Uint8Array expected");
|
|
1078
|
+
if (lengths.length > 0 && !lengths.includes(b.length))
|
|
1079
|
+
throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
|
|
1014
1080
|
}
|
|
1015
|
-
function
|
|
1016
|
-
|
|
1081
|
+
function ahash(h2) {
|
|
1082
|
+
if (typeof h2 !== "function" || typeof h2.create !== "function")
|
|
1083
|
+
throw new Error("Hash should be wrapped by utils.wrapConstructor");
|
|
1084
|
+
anumber(h2.outputLen);
|
|
1085
|
+
anumber(h2.blockLen);
|
|
1017
1086
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1087
|
+
function aexists2(instance, checkFinished = true) {
|
|
1088
|
+
if (instance.destroyed)
|
|
1089
|
+
throw new Error("Hash instance has been destroyed");
|
|
1090
|
+
if (checkFinished && instance.finished)
|
|
1091
|
+
throw new Error("Hash#digest() has already been called");
|
|
1022
1092
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1093
|
+
function aoutput2(out, instance) {
|
|
1094
|
+
abytes3(out);
|
|
1095
|
+
const min = instance.outputLen;
|
|
1096
|
+
if (out.length < min) {
|
|
1097
|
+
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
1098
|
+
}
|
|
1026
1099
|
}
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1100
|
+
|
|
1101
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.0/node_modules/@noble/hashes/esm/cryptoNode.js
|
|
1102
|
+
import * as nc from "crypto";
|
|
1103
|
+
var crypto2 = nc && typeof nc === "object" && "webcrypto" in nc ? nc.webcrypto : nc && typeof nc === "object" && "randomBytes" in nc ? nc : void 0;
|
|
1104
|
+
|
|
1105
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.0/node_modules/@noble/hashes/esm/utils.js
|
|
1106
|
+
var createView2 = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
1107
|
+
var rotr2 = (word, shift) => word << 32 - shift | word >>> shift;
|
|
1108
|
+
function utf8ToBytes2(str) {
|
|
1109
|
+
if (typeof str !== "string")
|
|
1110
|
+
throw new Error("utf8ToBytes expected string, got " + typeof str);
|
|
1111
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
1030
1112
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1113
|
+
function toBytes2(data) {
|
|
1114
|
+
if (typeof data === "string")
|
|
1115
|
+
data = utf8ToBytes2(data);
|
|
1116
|
+
abytes3(data);
|
|
1117
|
+
return data;
|
|
1033
1118
|
}
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1119
|
+
function concatBytes2(...arrays) {
|
|
1120
|
+
let sum = 0;
|
|
1121
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
1122
|
+
const a = arrays[i];
|
|
1123
|
+
abytes3(a);
|
|
1124
|
+
sum += a.length;
|
|
1125
|
+
}
|
|
1126
|
+
const res = new Uint8Array(sum);
|
|
1127
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
1128
|
+
const a = arrays[i];
|
|
1129
|
+
res.set(a, pad);
|
|
1130
|
+
pad += a.length;
|
|
1039
1131
|
}
|
|
1132
|
+
return res;
|
|
1040
1133
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1134
|
+
var Hash2 = class {
|
|
1135
|
+
// Safe version that clones internal state
|
|
1136
|
+
clone() {
|
|
1137
|
+
return this._cloneInto();
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
function wrapConstructor2(hashCons) {
|
|
1141
|
+
const hashC = (msg) => hashCons().update(toBytes2(msg)).digest();
|
|
1142
|
+
const tmp = hashCons();
|
|
1143
|
+
hashC.outputLen = tmp.outputLen;
|
|
1144
|
+
hashC.blockLen = tmp.blockLen;
|
|
1145
|
+
hashC.create = () => hashCons();
|
|
1146
|
+
return hashC;
|
|
1047
1147
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
const payloadB64 = token.slice(0, dotIdx);
|
|
1052
|
-
const sigB64 = token.slice(dotIdx + 1);
|
|
1053
|
-
let payloadBytes;
|
|
1054
|
-
let signature;
|
|
1055
|
-
try {
|
|
1056
|
-
payloadBytes = fromBase64Url(payloadB64);
|
|
1057
|
-
signature = fromBase64Url(sigB64);
|
|
1058
|
-
} catch {
|
|
1059
|
-
return null;
|
|
1148
|
+
function randomBytes2(bytesLength = 32) {
|
|
1149
|
+
if (crypto2 && typeof crypto2.getRandomValues === "function") {
|
|
1150
|
+
return crypto2.getRandomValues(new Uint8Array(bytesLength));
|
|
1060
1151
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
let payload;
|
|
1064
|
-
try {
|
|
1065
|
-
payload = JSON.parse(new TextDecoder().decode(payloadBytes));
|
|
1066
|
-
} catch {
|
|
1067
|
-
return null;
|
|
1152
|
+
if (crypto2 && typeof crypto2.randomBytes === "function") {
|
|
1153
|
+
return crypto2.randomBytes(bytesLength);
|
|
1068
1154
|
}
|
|
1069
|
-
|
|
1070
|
-
if (!payload.jti) return null;
|
|
1071
|
-
if (!payload.aud) return null;
|
|
1072
|
-
return payload;
|
|
1155
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
1073
1156
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1157
|
+
|
|
1158
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.0/node_modules/@noble/hashes/esm/_md.js
|
|
1159
|
+
function setBigUint642(view, byteOffset, value, isLE) {
|
|
1160
|
+
if (typeof view.setBigUint64 === "function")
|
|
1161
|
+
return view.setBigUint64(byteOffset, value, isLE);
|
|
1162
|
+
const _32n2 = BigInt(32);
|
|
1163
|
+
const _u32_max = BigInt(4294967295);
|
|
1164
|
+
const wh = Number(value >> _32n2 & _u32_max);
|
|
1165
|
+
const wl = Number(value & _u32_max);
|
|
1166
|
+
const h2 = isLE ? 4 : 0;
|
|
1167
|
+
const l = isLE ? 0 : 4;
|
|
1168
|
+
view.setUint32(byteOffset + h2, wh, isLE);
|
|
1169
|
+
view.setUint32(byteOffset + l, wl, isLE);
|
|
1079
1170
|
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1171
|
+
var Chi2 = (a, b, c) => a & b ^ ~a & c;
|
|
1172
|
+
var Maj2 = (a, b, c) => a & b ^ a & c ^ b & c;
|
|
1173
|
+
var HashMD2 = class extends Hash2 {
|
|
1174
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
1175
|
+
super();
|
|
1176
|
+
this.blockLen = blockLen;
|
|
1177
|
+
this.outputLen = outputLen;
|
|
1178
|
+
this.padOffset = padOffset;
|
|
1179
|
+
this.isLE = isLE;
|
|
1180
|
+
this.finished = false;
|
|
1181
|
+
this.length = 0;
|
|
1182
|
+
this.pos = 0;
|
|
1183
|
+
this.destroyed = false;
|
|
1184
|
+
this.buffer = new Uint8Array(blockLen);
|
|
1185
|
+
this.view = createView2(this.buffer);
|
|
1186
|
+
}
|
|
1187
|
+
update(data) {
|
|
1188
|
+
aexists2(this);
|
|
1189
|
+
const { view, buffer, blockLen } = this;
|
|
1190
|
+
data = toBytes2(data);
|
|
1191
|
+
const len = data.length;
|
|
1192
|
+
for (let pos = 0; pos < len; ) {
|
|
1193
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
1194
|
+
if (take === blockLen) {
|
|
1195
|
+
const dataView = createView2(data);
|
|
1196
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
1197
|
+
this.process(dataView, pos);
|
|
1198
|
+
continue;
|
|
1199
|
+
}
|
|
1200
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
1201
|
+
this.pos += take;
|
|
1202
|
+
pos += take;
|
|
1203
|
+
if (this.pos === blockLen) {
|
|
1204
|
+
this.process(view, 0);
|
|
1205
|
+
this.pos = 0;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
this.length += data.length;
|
|
1209
|
+
this.roundClean();
|
|
1210
|
+
return this;
|
|
1211
|
+
}
|
|
1212
|
+
digestInto(out) {
|
|
1213
|
+
aexists2(this);
|
|
1214
|
+
aoutput2(out, this);
|
|
1215
|
+
this.finished = true;
|
|
1216
|
+
const { buffer, view, blockLen, isLE } = this;
|
|
1217
|
+
let { pos } = this;
|
|
1218
|
+
buffer[pos++] = 128;
|
|
1219
|
+
this.buffer.subarray(pos).fill(0);
|
|
1220
|
+
if (this.padOffset > blockLen - pos) {
|
|
1221
|
+
this.process(view, 0);
|
|
1222
|
+
pos = 0;
|
|
1223
|
+
}
|
|
1224
|
+
for (let i = pos; i < blockLen; i++)
|
|
1225
|
+
buffer[i] = 0;
|
|
1226
|
+
setBigUint642(view, blockLen - 8, BigInt(this.length * 8), isLE);
|
|
1227
|
+
this.process(view, 0);
|
|
1228
|
+
const oview = createView2(out);
|
|
1229
|
+
const len = this.outputLen;
|
|
1230
|
+
if (len % 4)
|
|
1231
|
+
throw new Error("_sha2: outputLen should be aligned to 32bit");
|
|
1232
|
+
const outLen = len / 4;
|
|
1233
|
+
const state = this.get();
|
|
1234
|
+
if (outLen > state.length)
|
|
1235
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
1236
|
+
for (let i = 0; i < outLen; i++)
|
|
1237
|
+
oview.setUint32(4 * i, state[i], isLE);
|
|
1238
|
+
}
|
|
1239
|
+
digest() {
|
|
1240
|
+
const { buffer, outputLen } = this;
|
|
1241
|
+
this.digestInto(buffer);
|
|
1242
|
+
const res = buffer.slice(0, outputLen);
|
|
1243
|
+
this.destroy();
|
|
1244
|
+
return res;
|
|
1245
|
+
}
|
|
1246
|
+
_cloneInto(to) {
|
|
1247
|
+
to || (to = new this.constructor());
|
|
1248
|
+
to.set(...this.get());
|
|
1249
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
1250
|
+
to.length = length;
|
|
1251
|
+
to.pos = pos;
|
|
1252
|
+
to.finished = finished;
|
|
1253
|
+
to.destroyed = destroyed;
|
|
1254
|
+
if (length % blockLen)
|
|
1255
|
+
to.buffer.set(buffer);
|
|
1256
|
+
return to;
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.0/node_modules/@noble/hashes/esm/sha256.js
|
|
1261
|
+
var SHA256_K2 = /* @__PURE__ */ new Uint32Array([
|
|
1262
|
+
1116352408,
|
|
1263
|
+
1899447441,
|
|
1264
|
+
3049323471,
|
|
1265
|
+
3921009573,
|
|
1266
|
+
961987163,
|
|
1267
|
+
1508970993,
|
|
1268
|
+
2453635748,
|
|
1269
|
+
2870763221,
|
|
1270
|
+
3624381080,
|
|
1271
|
+
310598401,
|
|
1272
|
+
607225278,
|
|
1273
|
+
1426881987,
|
|
1274
|
+
1925078388,
|
|
1275
|
+
2162078206,
|
|
1276
|
+
2614888103,
|
|
1277
|
+
3248222580,
|
|
1278
|
+
3835390401,
|
|
1279
|
+
4022224774,
|
|
1280
|
+
264347078,
|
|
1281
|
+
604807628,
|
|
1282
|
+
770255983,
|
|
1283
|
+
1249150122,
|
|
1284
|
+
1555081692,
|
|
1285
|
+
1996064986,
|
|
1286
|
+
2554220882,
|
|
1287
|
+
2821834349,
|
|
1288
|
+
2952996808,
|
|
1289
|
+
3210313671,
|
|
1290
|
+
3336571891,
|
|
1291
|
+
3584528711,
|
|
1292
|
+
113926993,
|
|
1293
|
+
338241895,
|
|
1294
|
+
666307205,
|
|
1295
|
+
773529912,
|
|
1296
|
+
1294757372,
|
|
1297
|
+
1396182291,
|
|
1298
|
+
1695183700,
|
|
1299
|
+
1986661051,
|
|
1300
|
+
2177026350,
|
|
1301
|
+
2456956037,
|
|
1302
|
+
2730485921,
|
|
1303
|
+
2820302411,
|
|
1304
|
+
3259730800,
|
|
1305
|
+
3345764771,
|
|
1306
|
+
3516065817,
|
|
1307
|
+
3600352804,
|
|
1308
|
+
4094571909,
|
|
1309
|
+
275423344,
|
|
1310
|
+
430227734,
|
|
1311
|
+
506948616,
|
|
1312
|
+
659060556,
|
|
1313
|
+
883997877,
|
|
1314
|
+
958139571,
|
|
1315
|
+
1322822218,
|
|
1316
|
+
1537002063,
|
|
1317
|
+
1747873779,
|
|
1318
|
+
1955562222,
|
|
1319
|
+
2024104815,
|
|
1320
|
+
2227730452,
|
|
1321
|
+
2361852424,
|
|
1322
|
+
2428436474,
|
|
1323
|
+
2756734187,
|
|
1324
|
+
3204031479,
|
|
1325
|
+
3329325298
|
|
1326
|
+
]);
|
|
1327
|
+
var SHA256_IV2 = /* @__PURE__ */ new Uint32Array([
|
|
1328
|
+
1779033703,
|
|
1329
|
+
3144134277,
|
|
1330
|
+
1013904242,
|
|
1331
|
+
2773480762,
|
|
1332
|
+
1359893119,
|
|
1333
|
+
2600822924,
|
|
1334
|
+
528734635,
|
|
1335
|
+
1541459225
|
|
1336
|
+
]);
|
|
1337
|
+
var SHA256_W2 = /* @__PURE__ */ new Uint32Array(64);
|
|
1338
|
+
var SHA2562 = class extends HashMD2 {
|
|
1339
|
+
constructor() {
|
|
1340
|
+
super(64, 32, 8, false);
|
|
1341
|
+
this.A = SHA256_IV2[0] | 0;
|
|
1342
|
+
this.B = SHA256_IV2[1] | 0;
|
|
1343
|
+
this.C = SHA256_IV2[2] | 0;
|
|
1344
|
+
this.D = SHA256_IV2[3] | 0;
|
|
1345
|
+
this.E = SHA256_IV2[4] | 0;
|
|
1346
|
+
this.F = SHA256_IV2[5] | 0;
|
|
1347
|
+
this.G = SHA256_IV2[6] | 0;
|
|
1348
|
+
this.H = SHA256_IV2[7] | 0;
|
|
1349
|
+
}
|
|
1350
|
+
get() {
|
|
1351
|
+
const { A, B, C: C2, D, E, F, G: G2, H } = this;
|
|
1352
|
+
return [A, B, C2, D, E, F, G2, H];
|
|
1353
|
+
}
|
|
1354
|
+
// prettier-ignore
|
|
1355
|
+
set(A, B, C2, D, E, F, G2, H) {
|
|
1356
|
+
this.A = A | 0;
|
|
1357
|
+
this.B = B | 0;
|
|
1358
|
+
this.C = C2 | 0;
|
|
1359
|
+
this.D = D | 0;
|
|
1360
|
+
this.E = E | 0;
|
|
1361
|
+
this.F = F | 0;
|
|
1362
|
+
this.G = G2 | 0;
|
|
1363
|
+
this.H = H | 0;
|
|
1364
|
+
}
|
|
1365
|
+
process(view, offset) {
|
|
1366
|
+
for (let i = 0; i < 16; i++, offset += 4)
|
|
1367
|
+
SHA256_W2[i] = view.getUint32(offset, false);
|
|
1368
|
+
for (let i = 16; i < 64; i++) {
|
|
1369
|
+
const W15 = SHA256_W2[i - 15];
|
|
1370
|
+
const W2 = SHA256_W2[i - 2];
|
|
1371
|
+
const s0 = rotr2(W15, 7) ^ rotr2(W15, 18) ^ W15 >>> 3;
|
|
1372
|
+
const s1 = rotr2(W2, 17) ^ rotr2(W2, 19) ^ W2 >>> 10;
|
|
1373
|
+
SHA256_W2[i] = s1 + SHA256_W2[i - 7] + s0 + SHA256_W2[i - 16] | 0;
|
|
1374
|
+
}
|
|
1375
|
+
let { A, B, C: C2, D, E, F, G: G2, H } = this;
|
|
1376
|
+
for (let i = 0; i < 64; i++) {
|
|
1377
|
+
const sigma1 = rotr2(E, 6) ^ rotr2(E, 11) ^ rotr2(E, 25);
|
|
1378
|
+
const T1 = H + sigma1 + Chi2(E, F, G2) + SHA256_K2[i] + SHA256_W2[i] | 0;
|
|
1379
|
+
const sigma0 = rotr2(A, 2) ^ rotr2(A, 13) ^ rotr2(A, 22);
|
|
1380
|
+
const T2 = sigma0 + Maj2(A, B, C2) | 0;
|
|
1381
|
+
H = G2;
|
|
1382
|
+
G2 = F;
|
|
1383
|
+
F = E;
|
|
1384
|
+
E = D + T1 | 0;
|
|
1385
|
+
D = C2;
|
|
1386
|
+
C2 = B;
|
|
1387
|
+
B = A;
|
|
1388
|
+
A = T1 + T2 | 0;
|
|
1389
|
+
}
|
|
1390
|
+
A = A + this.A | 0;
|
|
1391
|
+
B = B + this.B | 0;
|
|
1392
|
+
C2 = C2 + this.C | 0;
|
|
1393
|
+
D = D + this.D | 0;
|
|
1394
|
+
E = E + this.E | 0;
|
|
1395
|
+
F = F + this.F | 0;
|
|
1396
|
+
G2 = G2 + this.G | 0;
|
|
1397
|
+
H = H + this.H | 0;
|
|
1398
|
+
this.set(A, B, C2, D, E, F, G2, H);
|
|
1399
|
+
}
|
|
1400
|
+
roundClean() {
|
|
1401
|
+
SHA256_W2.fill(0);
|
|
1402
|
+
}
|
|
1403
|
+
destroy() {
|
|
1404
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
1405
|
+
this.buffer.fill(0);
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
var sha2562 = /* @__PURE__ */ wrapConstructor2(() => new SHA2562());
|
|
1409
|
+
|
|
1410
|
+
// ../../node_modules/.pnpm/@noble+hashes@1.6.0/node_modules/@noble/hashes/esm/hmac.js
|
|
1411
|
+
var HMAC = class extends Hash2 {
|
|
1412
|
+
constructor(hash2, _key) {
|
|
1413
|
+
super();
|
|
1414
|
+
this.finished = false;
|
|
1415
|
+
this.destroyed = false;
|
|
1416
|
+
ahash(hash2);
|
|
1417
|
+
const key = toBytes2(_key);
|
|
1418
|
+
this.iHash = hash2.create();
|
|
1419
|
+
if (typeof this.iHash.update !== "function")
|
|
1420
|
+
throw new Error("Expected instance of class which extends utils.Hash");
|
|
1421
|
+
this.blockLen = this.iHash.blockLen;
|
|
1422
|
+
this.outputLen = this.iHash.outputLen;
|
|
1423
|
+
const blockLen = this.blockLen;
|
|
1424
|
+
const pad = new Uint8Array(blockLen);
|
|
1425
|
+
pad.set(key.length > blockLen ? hash2.create().update(key).digest() : key);
|
|
1426
|
+
for (let i = 0; i < pad.length; i++)
|
|
1427
|
+
pad[i] ^= 54;
|
|
1428
|
+
this.iHash.update(pad);
|
|
1429
|
+
this.oHash = hash2.create();
|
|
1430
|
+
for (let i = 0; i < pad.length; i++)
|
|
1431
|
+
pad[i] ^= 54 ^ 92;
|
|
1432
|
+
this.oHash.update(pad);
|
|
1433
|
+
pad.fill(0);
|
|
1434
|
+
}
|
|
1435
|
+
update(buf) {
|
|
1436
|
+
aexists2(this);
|
|
1437
|
+
this.iHash.update(buf);
|
|
1438
|
+
return this;
|
|
1439
|
+
}
|
|
1440
|
+
digestInto(out) {
|
|
1441
|
+
aexists2(this);
|
|
1442
|
+
abytes3(out, this.outputLen);
|
|
1443
|
+
this.finished = true;
|
|
1444
|
+
this.iHash.digestInto(out);
|
|
1445
|
+
this.oHash.update(out);
|
|
1446
|
+
this.oHash.digestInto(out);
|
|
1447
|
+
this.destroy();
|
|
1448
|
+
}
|
|
1449
|
+
digest() {
|
|
1450
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
|
1451
|
+
this.digestInto(out);
|
|
1452
|
+
return out;
|
|
1453
|
+
}
|
|
1454
|
+
_cloneInto(to) {
|
|
1455
|
+
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
|
1456
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
1457
|
+
to = to;
|
|
1458
|
+
to.finished = finished;
|
|
1459
|
+
to.destroyed = destroyed;
|
|
1460
|
+
to.blockLen = blockLen;
|
|
1461
|
+
to.outputLen = outputLen;
|
|
1462
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
|
1463
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
|
1464
|
+
return to;
|
|
1465
|
+
}
|
|
1466
|
+
destroy() {
|
|
1467
|
+
this.destroyed = true;
|
|
1468
|
+
this.oHash.destroy();
|
|
1469
|
+
this.iHash.destroy();
|
|
1470
|
+
}
|
|
1471
|
+
};
|
|
1472
|
+
var hmac = (hash2, key, message) => new HMAC(hash2, key).update(message).digest();
|
|
1473
|
+
hmac.create = (hash2, key) => new HMAC(hash2, key);
|
|
1474
|
+
|
|
1475
|
+
// ../../node_modules/.pnpm/@noble+curves@1.7.0/node_modules/@noble/curves/esm/abstract/utils.js
|
|
1476
|
+
var utils_exports = {};
|
|
1477
|
+
__export(utils_exports, {
|
|
1478
|
+
aInRange: () => aInRange,
|
|
1479
|
+
abool: () => abool,
|
|
1480
|
+
abytes: () => abytes4,
|
|
1481
|
+
bitGet: () => bitGet,
|
|
1482
|
+
bitLen: () => bitLen,
|
|
1483
|
+
bitMask: () => bitMask,
|
|
1484
|
+
bitSet: () => bitSet,
|
|
1485
|
+
bytesToHex: () => bytesToHex2,
|
|
1486
|
+
bytesToNumberBE: () => bytesToNumberBE,
|
|
1487
|
+
bytesToNumberLE: () => bytesToNumberLE2,
|
|
1488
|
+
concatBytes: () => concatBytes3,
|
|
1489
|
+
createHmacDrbg: () => createHmacDrbg,
|
|
1490
|
+
ensureBytes: () => ensureBytes,
|
|
1491
|
+
equalBytes: () => equalBytes,
|
|
1492
|
+
hexToBytes: () => hexToBytes2,
|
|
1493
|
+
hexToNumber: () => hexToNumber,
|
|
1494
|
+
inRange: () => inRange,
|
|
1495
|
+
isBytes: () => isBytes4,
|
|
1496
|
+
memoized: () => memoized,
|
|
1497
|
+
notImplemented: () => notImplemented,
|
|
1498
|
+
numberToBytesBE: () => numberToBytesBE,
|
|
1499
|
+
numberToBytesLE: () => numberToBytesLE,
|
|
1500
|
+
numberToHexUnpadded: () => numberToHexUnpadded,
|
|
1501
|
+
numberToVarBytesBE: () => numberToVarBytesBE,
|
|
1502
|
+
utf8ToBytes: () => utf8ToBytes3,
|
|
1503
|
+
validateObject: () => validateObject
|
|
1504
|
+
});
|
|
1505
|
+
var _0n = /* @__PURE__ */ BigInt(0);
|
|
1506
|
+
var _1n = /* @__PURE__ */ BigInt(1);
|
|
1507
|
+
var _2n = /* @__PURE__ */ BigInt(2);
|
|
1508
|
+
function isBytes4(a) {
|
|
1509
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
1510
|
+
}
|
|
1511
|
+
function abytes4(item) {
|
|
1512
|
+
if (!isBytes4(item))
|
|
1513
|
+
throw new Error("Uint8Array expected");
|
|
1514
|
+
}
|
|
1515
|
+
function abool(title, value) {
|
|
1516
|
+
if (typeof value !== "boolean")
|
|
1517
|
+
throw new Error(title + " boolean expected, got " + value);
|
|
1518
|
+
}
|
|
1519
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
1520
|
+
function bytesToHex2(bytes) {
|
|
1521
|
+
abytes4(bytes);
|
|
1522
|
+
let hex = "";
|
|
1523
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1524
|
+
hex += hexes[bytes[i]];
|
|
1525
|
+
}
|
|
1526
|
+
return hex;
|
|
1527
|
+
}
|
|
1528
|
+
function numberToHexUnpadded(num) {
|
|
1529
|
+
const hex = num.toString(16);
|
|
1530
|
+
return hex.length & 1 ? "0" + hex : hex;
|
|
1531
|
+
}
|
|
1532
|
+
function hexToNumber(hex) {
|
|
1533
|
+
if (typeof hex !== "string")
|
|
1534
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
1535
|
+
return hex === "" ? _0n : BigInt("0x" + hex);
|
|
1536
|
+
}
|
|
1537
|
+
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
1538
|
+
function asciiToBase16(ch) {
|
|
1539
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
1540
|
+
return ch - asciis._0;
|
|
1541
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
1542
|
+
return ch - (asciis.A - 10);
|
|
1543
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
1544
|
+
return ch - (asciis.a - 10);
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
function hexToBytes2(hex) {
|
|
1548
|
+
if (typeof hex !== "string")
|
|
1549
|
+
throw new Error("hex string expected, got " + typeof hex);
|
|
1550
|
+
const hl = hex.length;
|
|
1551
|
+
const al = hl / 2;
|
|
1552
|
+
if (hl % 2)
|
|
1553
|
+
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
1554
|
+
const array = new Uint8Array(al);
|
|
1555
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
1556
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
1557
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
1558
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
1559
|
+
const char = hex[hi] + hex[hi + 1];
|
|
1560
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
1561
|
+
}
|
|
1562
|
+
array[ai] = n1 * 16 + n2;
|
|
1563
|
+
}
|
|
1564
|
+
return array;
|
|
1565
|
+
}
|
|
1566
|
+
function bytesToNumberBE(bytes) {
|
|
1567
|
+
return hexToNumber(bytesToHex2(bytes));
|
|
1568
|
+
}
|
|
1569
|
+
function bytesToNumberLE2(bytes) {
|
|
1570
|
+
abytes4(bytes);
|
|
1571
|
+
return hexToNumber(bytesToHex2(Uint8Array.from(bytes).reverse()));
|
|
1572
|
+
}
|
|
1573
|
+
function numberToBytesBE(n, len) {
|
|
1574
|
+
return hexToBytes2(n.toString(16).padStart(len * 2, "0"));
|
|
1575
|
+
}
|
|
1576
|
+
function numberToBytesLE(n, len) {
|
|
1577
|
+
return numberToBytesBE(n, len).reverse();
|
|
1578
|
+
}
|
|
1579
|
+
function numberToVarBytesBE(n) {
|
|
1580
|
+
return hexToBytes2(numberToHexUnpadded(n));
|
|
1581
|
+
}
|
|
1582
|
+
function ensureBytes(title, hex, expectedLength) {
|
|
1583
|
+
let res;
|
|
1584
|
+
if (typeof hex === "string") {
|
|
1585
|
+
try {
|
|
1586
|
+
res = hexToBytes2(hex);
|
|
1587
|
+
} catch (e) {
|
|
1588
|
+
throw new Error(title + " must be hex string or Uint8Array, cause: " + e);
|
|
1589
|
+
}
|
|
1590
|
+
} else if (isBytes4(hex)) {
|
|
1591
|
+
res = Uint8Array.from(hex);
|
|
1592
|
+
} else {
|
|
1593
|
+
throw new Error(title + " must be hex string or Uint8Array");
|
|
1594
|
+
}
|
|
1595
|
+
const len = res.length;
|
|
1596
|
+
if (typeof expectedLength === "number" && len !== expectedLength)
|
|
1597
|
+
throw new Error(title + " of length " + expectedLength + " expected, got " + len);
|
|
1598
|
+
return res;
|
|
1599
|
+
}
|
|
1600
|
+
function concatBytes3(...arrays) {
|
|
1601
|
+
let sum = 0;
|
|
1602
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
1603
|
+
const a = arrays[i];
|
|
1604
|
+
abytes4(a);
|
|
1605
|
+
sum += a.length;
|
|
1606
|
+
}
|
|
1607
|
+
const res = new Uint8Array(sum);
|
|
1608
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
1609
|
+
const a = arrays[i];
|
|
1610
|
+
res.set(a, pad);
|
|
1611
|
+
pad += a.length;
|
|
1612
|
+
}
|
|
1613
|
+
return res;
|
|
1614
|
+
}
|
|
1615
|
+
function equalBytes(a, b) {
|
|
1616
|
+
if (a.length !== b.length)
|
|
1617
|
+
return false;
|
|
1618
|
+
let diff = 0;
|
|
1619
|
+
for (let i = 0; i < a.length; i++)
|
|
1620
|
+
diff |= a[i] ^ b[i];
|
|
1621
|
+
return diff === 0;
|
|
1622
|
+
}
|
|
1623
|
+
function utf8ToBytes3(str) {
|
|
1624
|
+
if (typeof str !== "string")
|
|
1625
|
+
throw new Error("string expected");
|
|
1626
|
+
return new Uint8Array(new TextEncoder().encode(str));
|
|
1627
|
+
}
|
|
1628
|
+
var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
1629
|
+
function inRange(n, min, max) {
|
|
1630
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
1631
|
+
}
|
|
1632
|
+
function aInRange(title, n, min, max) {
|
|
1633
|
+
if (!inRange(n, min, max))
|
|
1634
|
+
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
1635
|
+
}
|
|
1636
|
+
function bitLen(n) {
|
|
1637
|
+
let len;
|
|
1638
|
+
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
1639
|
+
;
|
|
1640
|
+
return len;
|
|
1641
|
+
}
|
|
1642
|
+
function bitGet(n, pos) {
|
|
1643
|
+
return n >> BigInt(pos) & _1n;
|
|
1644
|
+
}
|
|
1645
|
+
function bitSet(n, pos, value) {
|
|
1646
|
+
return n | (value ? _1n : _0n) << BigInt(pos);
|
|
1647
|
+
}
|
|
1648
|
+
var bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
|
|
1649
|
+
var u8n2 = (data) => new Uint8Array(data);
|
|
1650
|
+
var u8fr2 = (arr) => Uint8Array.from(arr);
|
|
1651
|
+
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
1652
|
+
if (typeof hashLen !== "number" || hashLen < 2)
|
|
1653
|
+
throw new Error("hashLen must be a number");
|
|
1654
|
+
if (typeof qByteLen !== "number" || qByteLen < 2)
|
|
1655
|
+
throw new Error("qByteLen must be a number");
|
|
1656
|
+
if (typeof hmacFn !== "function")
|
|
1657
|
+
throw new Error("hmacFn must be a function");
|
|
1658
|
+
let v = u8n2(hashLen);
|
|
1659
|
+
let k = u8n2(hashLen);
|
|
1660
|
+
let i = 0;
|
|
1661
|
+
const reset = () => {
|
|
1662
|
+
v.fill(1);
|
|
1663
|
+
k.fill(0);
|
|
1664
|
+
i = 0;
|
|
1665
|
+
};
|
|
1666
|
+
const h2 = (...b) => hmacFn(k, v, ...b);
|
|
1667
|
+
const reseed = (seed = u8n2()) => {
|
|
1668
|
+
k = h2(u8fr2([0]), seed);
|
|
1669
|
+
v = h2();
|
|
1670
|
+
if (seed.length === 0)
|
|
1671
|
+
return;
|
|
1672
|
+
k = h2(u8fr2([1]), seed);
|
|
1673
|
+
v = h2();
|
|
1674
|
+
};
|
|
1675
|
+
const gen = () => {
|
|
1676
|
+
if (i++ >= 1e3)
|
|
1677
|
+
throw new Error("drbg: tried 1000 values");
|
|
1678
|
+
let len = 0;
|
|
1679
|
+
const out = [];
|
|
1680
|
+
while (len < qByteLen) {
|
|
1681
|
+
v = h2();
|
|
1682
|
+
const sl = v.slice();
|
|
1683
|
+
out.push(sl);
|
|
1684
|
+
len += v.length;
|
|
1685
|
+
}
|
|
1686
|
+
return concatBytes3(...out);
|
|
1687
|
+
};
|
|
1688
|
+
const genUntil = (seed, pred) => {
|
|
1689
|
+
reset();
|
|
1690
|
+
reseed(seed);
|
|
1691
|
+
let res = void 0;
|
|
1692
|
+
while (!(res = pred(gen())))
|
|
1693
|
+
reseed();
|
|
1694
|
+
reset();
|
|
1695
|
+
return res;
|
|
1696
|
+
};
|
|
1697
|
+
return genUntil;
|
|
1698
|
+
}
|
|
1699
|
+
var validatorFns = {
|
|
1700
|
+
bigint: (val) => typeof val === "bigint",
|
|
1701
|
+
function: (val) => typeof val === "function",
|
|
1702
|
+
boolean: (val) => typeof val === "boolean",
|
|
1703
|
+
string: (val) => typeof val === "string",
|
|
1704
|
+
stringOrUint8Array: (val) => typeof val === "string" || isBytes4(val),
|
|
1705
|
+
isSafeInteger: (val) => Number.isSafeInteger(val),
|
|
1706
|
+
array: (val) => Array.isArray(val),
|
|
1707
|
+
field: (val, object) => object.Fp.isValid(val),
|
|
1708
|
+
hash: (val) => typeof val === "function" && Number.isSafeInteger(val.outputLen)
|
|
1709
|
+
};
|
|
1710
|
+
function validateObject(object, validators, optValidators = {}) {
|
|
1711
|
+
const checkField = (fieldName, type, isOptional) => {
|
|
1712
|
+
const checkVal = validatorFns[type];
|
|
1713
|
+
if (typeof checkVal !== "function")
|
|
1714
|
+
throw new Error("invalid validator function");
|
|
1715
|
+
const val = object[fieldName];
|
|
1716
|
+
if (isOptional && val === void 0)
|
|
1717
|
+
return;
|
|
1718
|
+
if (!checkVal(val, object)) {
|
|
1719
|
+
throw new Error("param " + String(fieldName) + " is invalid. Expected " + type + ", got " + val);
|
|
1720
|
+
}
|
|
1721
|
+
};
|
|
1722
|
+
for (const [fieldName, type] of Object.entries(validators))
|
|
1723
|
+
checkField(fieldName, type, false);
|
|
1724
|
+
for (const [fieldName, type] of Object.entries(optValidators))
|
|
1725
|
+
checkField(fieldName, type, true);
|
|
1726
|
+
return object;
|
|
1727
|
+
}
|
|
1728
|
+
var notImplemented = () => {
|
|
1729
|
+
throw new Error("not implemented");
|
|
1730
|
+
};
|
|
1731
|
+
function memoized(fn) {
|
|
1732
|
+
const map = /* @__PURE__ */ new WeakMap();
|
|
1733
|
+
return (arg, ...args) => {
|
|
1734
|
+
const val = map.get(arg);
|
|
1735
|
+
if (val !== void 0)
|
|
1736
|
+
return val;
|
|
1737
|
+
const computed = fn(arg, ...args);
|
|
1738
|
+
map.set(arg, computed);
|
|
1739
|
+
return computed;
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// ../../node_modules/.pnpm/@noble+curves@1.7.0/node_modules/@noble/curves/esm/abstract/modular.js
|
|
1744
|
+
var _0n2 = BigInt(0);
|
|
1745
|
+
var _1n2 = BigInt(1);
|
|
1746
|
+
var _2n2 = /* @__PURE__ */ BigInt(2);
|
|
1747
|
+
var _3n = /* @__PURE__ */ BigInt(3);
|
|
1748
|
+
var _4n = /* @__PURE__ */ BigInt(4);
|
|
1749
|
+
var _5n = /* @__PURE__ */ BigInt(5);
|
|
1750
|
+
var _8n = /* @__PURE__ */ BigInt(8);
|
|
1751
|
+
var _9n = /* @__PURE__ */ BigInt(9);
|
|
1752
|
+
var _16n = /* @__PURE__ */ BigInt(16);
|
|
1753
|
+
function mod(a, b) {
|
|
1754
|
+
const result = a % b;
|
|
1755
|
+
return result >= _0n2 ? result : b + result;
|
|
1756
|
+
}
|
|
1757
|
+
function pow(num, power, modulo) {
|
|
1758
|
+
if (power < _0n2)
|
|
1759
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
1760
|
+
if (modulo <= _0n2)
|
|
1761
|
+
throw new Error("invalid modulus");
|
|
1762
|
+
if (modulo === _1n2)
|
|
1763
|
+
return _0n2;
|
|
1764
|
+
let res = _1n2;
|
|
1765
|
+
while (power > _0n2) {
|
|
1766
|
+
if (power & _1n2)
|
|
1767
|
+
res = res * num % modulo;
|
|
1768
|
+
num = num * num % modulo;
|
|
1769
|
+
power >>= _1n2;
|
|
1770
|
+
}
|
|
1771
|
+
return res;
|
|
1772
|
+
}
|
|
1773
|
+
function invert2(number, modulo) {
|
|
1774
|
+
if (number === _0n2)
|
|
1775
|
+
throw new Error("invert: expected non-zero number");
|
|
1776
|
+
if (modulo <= _0n2)
|
|
1777
|
+
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
1778
|
+
let a = mod(number, modulo);
|
|
1779
|
+
let b = modulo;
|
|
1780
|
+
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
1781
|
+
while (a !== _0n2) {
|
|
1782
|
+
const q = b / a;
|
|
1783
|
+
const r = b % a;
|
|
1784
|
+
const m = x - u * q;
|
|
1785
|
+
const n = y - v * q;
|
|
1786
|
+
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
1787
|
+
}
|
|
1788
|
+
const gcd = b;
|
|
1789
|
+
if (gcd !== _1n2)
|
|
1790
|
+
throw new Error("invert: does not exist");
|
|
1791
|
+
return mod(x, modulo);
|
|
1792
|
+
}
|
|
1793
|
+
function tonelliShanks(P2) {
|
|
1794
|
+
const legendreC = (P2 - _1n2) / _2n2;
|
|
1795
|
+
let Q, S, Z;
|
|
1796
|
+
for (Q = P2 - _1n2, S = 0; Q % _2n2 === _0n2; Q /= _2n2, S++)
|
|
1797
|
+
;
|
|
1798
|
+
for (Z = _2n2; Z < P2 && pow(Z, legendreC, P2) !== P2 - _1n2; Z++) {
|
|
1799
|
+
if (Z > 1e3)
|
|
1800
|
+
throw new Error("Cannot find square root: likely non-prime P");
|
|
1801
|
+
}
|
|
1802
|
+
if (S === 1) {
|
|
1803
|
+
const p1div4 = (P2 + _1n2) / _4n;
|
|
1804
|
+
return function tonelliFast(Fp, n) {
|
|
1805
|
+
const root = Fp.pow(n, p1div4);
|
|
1806
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
1807
|
+
throw new Error("Cannot find square root");
|
|
1808
|
+
return root;
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
const Q1div2 = (Q + _1n2) / _2n2;
|
|
1812
|
+
return function tonelliSlow(Fp, n) {
|
|
1813
|
+
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))
|
|
1814
|
+
throw new Error("Cannot find square root");
|
|
1815
|
+
let r = S;
|
|
1816
|
+
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q);
|
|
1817
|
+
let x = Fp.pow(n, Q1div2);
|
|
1818
|
+
let b = Fp.pow(n, Q);
|
|
1819
|
+
while (!Fp.eql(b, Fp.ONE)) {
|
|
1820
|
+
if (Fp.eql(b, Fp.ZERO))
|
|
1821
|
+
return Fp.ZERO;
|
|
1822
|
+
let m = 1;
|
|
1823
|
+
for (let t2 = Fp.sqr(b); m < r; m++) {
|
|
1824
|
+
if (Fp.eql(t2, Fp.ONE))
|
|
1825
|
+
break;
|
|
1826
|
+
t2 = Fp.sqr(t2);
|
|
1827
|
+
}
|
|
1828
|
+
const ge = Fp.pow(g, _1n2 << BigInt(r - m - 1));
|
|
1829
|
+
g = Fp.sqr(ge);
|
|
1830
|
+
x = Fp.mul(x, ge);
|
|
1831
|
+
b = Fp.mul(b, g);
|
|
1832
|
+
r = m;
|
|
1833
|
+
}
|
|
1834
|
+
return x;
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
function FpSqrt(P2) {
|
|
1838
|
+
if (P2 % _4n === _3n) {
|
|
1839
|
+
const p1div4 = (P2 + _1n2) / _4n;
|
|
1840
|
+
return function sqrt3mod4(Fp, n) {
|
|
1841
|
+
const root = Fp.pow(n, p1div4);
|
|
1842
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
1843
|
+
throw new Error("Cannot find square root");
|
|
1844
|
+
return root;
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
if (P2 % _8n === _5n) {
|
|
1848
|
+
const c1 = (P2 - _5n) / _8n;
|
|
1849
|
+
return function sqrt5mod8(Fp, n) {
|
|
1850
|
+
const n2 = Fp.mul(n, _2n2);
|
|
1851
|
+
const v = Fp.pow(n2, c1);
|
|
1852
|
+
const nv = Fp.mul(n, v);
|
|
1853
|
+
const i = Fp.mul(Fp.mul(nv, _2n2), v);
|
|
1854
|
+
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
1855
|
+
if (!Fp.eql(Fp.sqr(root), n))
|
|
1856
|
+
throw new Error("Cannot find square root");
|
|
1857
|
+
return root;
|
|
1858
|
+
};
|
|
1859
|
+
}
|
|
1860
|
+
if (P2 % _16n === _9n) {
|
|
1861
|
+
}
|
|
1862
|
+
return tonelliShanks(P2);
|
|
1863
|
+
}
|
|
1864
|
+
var FIELD_FIELDS = [
|
|
1865
|
+
"create",
|
|
1866
|
+
"isValid",
|
|
1867
|
+
"is0",
|
|
1868
|
+
"neg",
|
|
1869
|
+
"inv",
|
|
1870
|
+
"sqrt",
|
|
1871
|
+
"sqr",
|
|
1872
|
+
"eql",
|
|
1873
|
+
"add",
|
|
1874
|
+
"sub",
|
|
1875
|
+
"mul",
|
|
1876
|
+
"pow",
|
|
1877
|
+
"div",
|
|
1878
|
+
"addN",
|
|
1879
|
+
"subN",
|
|
1880
|
+
"mulN",
|
|
1881
|
+
"sqrN"
|
|
1882
|
+
];
|
|
1883
|
+
function validateField(field) {
|
|
1884
|
+
const initial = {
|
|
1885
|
+
ORDER: "bigint",
|
|
1886
|
+
MASK: "bigint",
|
|
1887
|
+
BYTES: "isSafeInteger",
|
|
1888
|
+
BITS: "isSafeInteger"
|
|
1889
|
+
};
|
|
1890
|
+
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
1891
|
+
map[val] = "function";
|
|
1892
|
+
return map;
|
|
1893
|
+
}, initial);
|
|
1894
|
+
return validateObject(field, opts);
|
|
1895
|
+
}
|
|
1896
|
+
function FpPow(f, num, power) {
|
|
1897
|
+
if (power < _0n2)
|
|
1898
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
1899
|
+
if (power === _0n2)
|
|
1900
|
+
return f.ONE;
|
|
1901
|
+
if (power === _1n2)
|
|
1902
|
+
return num;
|
|
1903
|
+
let p = f.ONE;
|
|
1904
|
+
let d = num;
|
|
1905
|
+
while (power > _0n2) {
|
|
1906
|
+
if (power & _1n2)
|
|
1907
|
+
p = f.mul(p, d);
|
|
1908
|
+
d = f.sqr(d);
|
|
1909
|
+
power >>= _1n2;
|
|
1910
|
+
}
|
|
1911
|
+
return p;
|
|
1912
|
+
}
|
|
1913
|
+
function FpInvertBatch(f, nums) {
|
|
1914
|
+
const tmp = new Array(nums.length);
|
|
1915
|
+
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
1916
|
+
if (f.is0(num))
|
|
1917
|
+
return acc;
|
|
1918
|
+
tmp[i] = acc;
|
|
1919
|
+
return f.mul(acc, num);
|
|
1920
|
+
}, f.ONE);
|
|
1921
|
+
const inverted = f.inv(lastMultiplied);
|
|
1922
|
+
nums.reduceRight((acc, num, i) => {
|
|
1923
|
+
if (f.is0(num))
|
|
1924
|
+
return acc;
|
|
1925
|
+
tmp[i] = f.mul(acc, tmp[i]);
|
|
1926
|
+
return f.mul(acc, num);
|
|
1927
|
+
}, inverted);
|
|
1928
|
+
return tmp;
|
|
1929
|
+
}
|
|
1930
|
+
function nLength(n, nBitLength) {
|
|
1931
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : n.toString(2).length;
|
|
1932
|
+
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
1933
|
+
return { nBitLength: _nBitLength, nByteLength };
|
|
1934
|
+
}
|
|
1935
|
+
function Field(ORDER, bitLen2, isLE = false, redef = {}) {
|
|
1936
|
+
if (ORDER <= _0n2)
|
|
1937
|
+
throw new Error("invalid field: expected ORDER > 0, got " + ORDER);
|
|
1938
|
+
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen2);
|
|
1939
|
+
if (BYTES > 2048)
|
|
1940
|
+
throw new Error("invalid field: expected ORDER of <= 2048 bytes");
|
|
1941
|
+
let sqrtP;
|
|
1942
|
+
const f = Object.freeze({
|
|
1943
|
+
ORDER,
|
|
1944
|
+
BITS,
|
|
1945
|
+
BYTES,
|
|
1946
|
+
MASK: bitMask(BITS),
|
|
1947
|
+
ZERO: _0n2,
|
|
1948
|
+
ONE: _1n2,
|
|
1949
|
+
create: (num) => mod(num, ORDER),
|
|
1950
|
+
isValid: (num) => {
|
|
1951
|
+
if (typeof num !== "bigint")
|
|
1952
|
+
throw new Error("invalid field element: expected bigint, got " + typeof num);
|
|
1953
|
+
return _0n2 <= num && num < ORDER;
|
|
1954
|
+
},
|
|
1955
|
+
is0: (num) => num === _0n2,
|
|
1956
|
+
isOdd: (num) => (num & _1n2) === _1n2,
|
|
1957
|
+
neg: (num) => mod(-num, ORDER),
|
|
1958
|
+
eql: (lhs, rhs) => lhs === rhs,
|
|
1959
|
+
sqr: (num) => mod(num * num, ORDER),
|
|
1960
|
+
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
|
1961
|
+
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
|
1962
|
+
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
|
1963
|
+
pow: (num, power) => FpPow(f, num, power),
|
|
1964
|
+
div: (lhs, rhs) => mod(lhs * invert2(rhs, ORDER), ORDER),
|
|
1965
|
+
// Same as above, but doesn't normalize
|
|
1966
|
+
sqrN: (num) => num * num,
|
|
1967
|
+
addN: (lhs, rhs) => lhs + rhs,
|
|
1968
|
+
subN: (lhs, rhs) => lhs - rhs,
|
|
1969
|
+
mulN: (lhs, rhs) => lhs * rhs,
|
|
1970
|
+
inv: (num) => invert2(num, ORDER),
|
|
1971
|
+
sqrt: redef.sqrt || ((n) => {
|
|
1972
|
+
if (!sqrtP)
|
|
1973
|
+
sqrtP = FpSqrt(ORDER);
|
|
1974
|
+
return sqrtP(f, n);
|
|
1975
|
+
}),
|
|
1976
|
+
invertBatch: (lst) => FpInvertBatch(f, lst),
|
|
1977
|
+
// TODO: do we really need constant cmov?
|
|
1978
|
+
// We don't have const-time bigints anyway, so probably will be not very useful
|
|
1979
|
+
cmov: (a, b, c) => c ? b : a,
|
|
1980
|
+
toBytes: (num) => isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES),
|
|
1981
|
+
fromBytes: (bytes) => {
|
|
1982
|
+
if (bytes.length !== BYTES)
|
|
1983
|
+
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
1984
|
+
return isLE ? bytesToNumberLE2(bytes) : bytesToNumberBE(bytes);
|
|
1985
|
+
}
|
|
1986
|
+
});
|
|
1987
|
+
return Object.freeze(f);
|
|
1988
|
+
}
|
|
1989
|
+
function getFieldBytesLength(fieldOrder) {
|
|
1990
|
+
if (typeof fieldOrder !== "bigint")
|
|
1991
|
+
throw new Error("field order must be bigint");
|
|
1992
|
+
const bitLength = fieldOrder.toString(2).length;
|
|
1993
|
+
return Math.ceil(bitLength / 8);
|
|
1994
|
+
}
|
|
1995
|
+
function getMinHashLength(fieldOrder) {
|
|
1996
|
+
const length = getFieldBytesLength(fieldOrder);
|
|
1997
|
+
return length + Math.ceil(length / 2);
|
|
1998
|
+
}
|
|
1999
|
+
function mapHashToField(key, fieldOrder, isLE = false) {
|
|
2000
|
+
const len = key.length;
|
|
2001
|
+
const fieldLen = getFieldBytesLength(fieldOrder);
|
|
2002
|
+
const minLen = getMinHashLength(fieldOrder);
|
|
2003
|
+
if (len < 16 || len < minLen || len > 1024)
|
|
2004
|
+
throw new Error("expected " + minLen + "-1024 bytes of input, got " + len);
|
|
2005
|
+
const num = isLE ? bytesToNumberBE(key) : bytesToNumberLE2(key);
|
|
2006
|
+
const reduced = mod(num, fieldOrder - _1n2) + _1n2;
|
|
2007
|
+
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
// ../../node_modules/.pnpm/@noble+curves@1.7.0/node_modules/@noble/curves/esm/abstract/curve.js
|
|
2011
|
+
var _0n3 = BigInt(0);
|
|
2012
|
+
var _1n3 = BigInt(1);
|
|
2013
|
+
function constTimeNegate(condition, item) {
|
|
2014
|
+
const neg = item.negate();
|
|
2015
|
+
return condition ? neg : item;
|
|
2016
|
+
}
|
|
2017
|
+
function validateW(W2, bits) {
|
|
2018
|
+
if (!Number.isSafeInteger(W2) || W2 <= 0 || W2 > bits)
|
|
2019
|
+
throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W2);
|
|
2020
|
+
}
|
|
2021
|
+
function calcWOpts(W2, bits) {
|
|
2022
|
+
validateW(W2, bits);
|
|
2023
|
+
const windows = Math.ceil(bits / W2) + 1;
|
|
2024
|
+
const windowSize = 2 ** (W2 - 1);
|
|
2025
|
+
return { windows, windowSize };
|
|
2026
|
+
}
|
|
2027
|
+
function validateMSMPoints(points, c) {
|
|
2028
|
+
if (!Array.isArray(points))
|
|
2029
|
+
throw new Error("array expected");
|
|
2030
|
+
points.forEach((p, i) => {
|
|
2031
|
+
if (!(p instanceof c))
|
|
2032
|
+
throw new Error("invalid point at index " + i);
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
function validateMSMScalars(scalars, field) {
|
|
2036
|
+
if (!Array.isArray(scalars))
|
|
2037
|
+
throw new Error("array of scalars expected");
|
|
2038
|
+
scalars.forEach((s, i) => {
|
|
2039
|
+
if (!field.isValid(s))
|
|
2040
|
+
throw new Error("invalid scalar at index " + i);
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
var pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
2044
|
+
var pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
2045
|
+
function getW(P2) {
|
|
2046
|
+
return pointWindowSizes.get(P2) || 1;
|
|
2047
|
+
}
|
|
2048
|
+
function wNAF2(c, bits) {
|
|
2049
|
+
return {
|
|
2050
|
+
constTimeNegate,
|
|
2051
|
+
hasPrecomputes(elm) {
|
|
2052
|
+
return getW(elm) !== 1;
|
|
2053
|
+
},
|
|
2054
|
+
// non-const time multiplication ladder
|
|
2055
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
|
2056
|
+
let d = elm;
|
|
2057
|
+
while (n > _0n3) {
|
|
2058
|
+
if (n & _1n3)
|
|
2059
|
+
p = p.add(d);
|
|
2060
|
+
d = d.double();
|
|
2061
|
+
n >>= _1n3;
|
|
2062
|
+
}
|
|
2063
|
+
return p;
|
|
2064
|
+
},
|
|
2065
|
+
/**
|
|
2066
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
2067
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
2068
|
+
* Number of precomputed points depends on the curve size:
|
|
2069
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
2070
|
+
* - 𝑊 is the window size
|
|
2071
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
2072
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
2073
|
+
* @param elm Point instance
|
|
2074
|
+
* @param W window size
|
|
2075
|
+
* @returns precomputed point tables flattened to a single array
|
|
2076
|
+
*/
|
|
2077
|
+
precomputeWindow(elm, W2) {
|
|
2078
|
+
const { windows, windowSize } = calcWOpts(W2, bits);
|
|
2079
|
+
const points = [];
|
|
2080
|
+
let p = elm;
|
|
2081
|
+
let base = p;
|
|
2082
|
+
for (let window = 0; window < windows; window++) {
|
|
2083
|
+
base = p;
|
|
2084
|
+
points.push(base);
|
|
2085
|
+
for (let i = 1; i < windowSize; i++) {
|
|
2086
|
+
base = base.add(p);
|
|
2087
|
+
points.push(base);
|
|
2088
|
+
}
|
|
2089
|
+
p = base.double();
|
|
2090
|
+
}
|
|
2091
|
+
return points;
|
|
2092
|
+
},
|
|
2093
|
+
/**
|
|
2094
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
2095
|
+
* @param W window size
|
|
2096
|
+
* @param precomputes precomputed tables
|
|
2097
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
|
2098
|
+
* @returns real and fake (for const-time) points
|
|
2099
|
+
*/
|
|
2100
|
+
wNAF(W2, precomputes, n) {
|
|
2101
|
+
const { windows, windowSize } = calcWOpts(W2, bits);
|
|
2102
|
+
let p = c.ZERO;
|
|
2103
|
+
let f = c.BASE;
|
|
2104
|
+
const mask = BigInt(2 ** W2 - 1);
|
|
2105
|
+
const maxNumber = 2 ** W2;
|
|
2106
|
+
const shiftBy = BigInt(W2);
|
|
2107
|
+
for (let window = 0; window < windows; window++) {
|
|
2108
|
+
const offset = window * windowSize;
|
|
2109
|
+
let wbits = Number(n & mask);
|
|
2110
|
+
n >>= shiftBy;
|
|
2111
|
+
if (wbits > windowSize) {
|
|
2112
|
+
wbits -= maxNumber;
|
|
2113
|
+
n += _1n3;
|
|
2114
|
+
}
|
|
2115
|
+
const offset1 = offset;
|
|
2116
|
+
const offset2 = offset + Math.abs(wbits) - 1;
|
|
2117
|
+
const cond1 = window % 2 !== 0;
|
|
2118
|
+
const cond2 = wbits < 0;
|
|
2119
|
+
if (wbits === 0) {
|
|
2120
|
+
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
|
2121
|
+
} else {
|
|
2122
|
+
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
return { p, f };
|
|
2126
|
+
},
|
|
2127
|
+
/**
|
|
2128
|
+
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
|
2129
|
+
* @param W window size
|
|
2130
|
+
* @param precomputes precomputed tables
|
|
2131
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
|
2132
|
+
* @param acc accumulator point to add result of multiplication
|
|
2133
|
+
* @returns point
|
|
2134
|
+
*/
|
|
2135
|
+
wNAFUnsafe(W2, precomputes, n, acc = c.ZERO) {
|
|
2136
|
+
const { windows, windowSize } = calcWOpts(W2, bits);
|
|
2137
|
+
const mask = BigInt(2 ** W2 - 1);
|
|
2138
|
+
const maxNumber = 2 ** W2;
|
|
2139
|
+
const shiftBy = BigInt(W2);
|
|
2140
|
+
for (let window = 0; window < windows; window++) {
|
|
2141
|
+
const offset = window * windowSize;
|
|
2142
|
+
if (n === _0n3)
|
|
2143
|
+
break;
|
|
2144
|
+
let wbits = Number(n & mask);
|
|
2145
|
+
n >>= shiftBy;
|
|
2146
|
+
if (wbits > windowSize) {
|
|
2147
|
+
wbits -= maxNumber;
|
|
2148
|
+
n += _1n3;
|
|
2149
|
+
}
|
|
2150
|
+
if (wbits === 0)
|
|
2151
|
+
continue;
|
|
2152
|
+
let curr = precomputes[offset + Math.abs(wbits) - 1];
|
|
2153
|
+
if (wbits < 0)
|
|
2154
|
+
curr = curr.negate();
|
|
2155
|
+
acc = acc.add(curr);
|
|
2156
|
+
}
|
|
2157
|
+
return acc;
|
|
2158
|
+
},
|
|
2159
|
+
getPrecomputes(W2, P2, transform) {
|
|
2160
|
+
let comp = pointPrecomputes.get(P2);
|
|
2161
|
+
if (!comp) {
|
|
2162
|
+
comp = this.precomputeWindow(P2, W2);
|
|
2163
|
+
if (W2 !== 1)
|
|
2164
|
+
pointPrecomputes.set(P2, transform(comp));
|
|
2165
|
+
}
|
|
2166
|
+
return comp;
|
|
2167
|
+
},
|
|
2168
|
+
wNAFCached(P2, n, transform) {
|
|
2169
|
+
const W2 = getW(P2);
|
|
2170
|
+
return this.wNAF(W2, this.getPrecomputes(W2, P2, transform), n);
|
|
2171
|
+
},
|
|
2172
|
+
wNAFCachedUnsafe(P2, n, transform, prev) {
|
|
2173
|
+
const W2 = getW(P2);
|
|
2174
|
+
if (W2 === 1)
|
|
2175
|
+
return this.unsafeLadder(P2, n, prev);
|
|
2176
|
+
return this.wNAFUnsafe(W2, this.getPrecomputes(W2, P2, transform), n, prev);
|
|
2177
|
+
},
|
|
2178
|
+
// We calculate precomputes for elliptic curve point multiplication
|
|
2179
|
+
// using windowed method. This specifies window size and
|
|
2180
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
|
2181
|
+
setWindowSize(P2, W2) {
|
|
2182
|
+
validateW(W2, bits);
|
|
2183
|
+
pointWindowSizes.set(P2, W2);
|
|
2184
|
+
pointPrecomputes.delete(P2);
|
|
2185
|
+
}
|
|
2186
|
+
};
|
|
2187
|
+
}
|
|
2188
|
+
function pippenger(c, fieldN, points, scalars) {
|
|
2189
|
+
validateMSMPoints(points, c);
|
|
2190
|
+
validateMSMScalars(scalars, fieldN);
|
|
2191
|
+
if (points.length !== scalars.length)
|
|
2192
|
+
throw new Error("arrays of points and scalars must have equal length");
|
|
2193
|
+
const zero = c.ZERO;
|
|
2194
|
+
const wbits = bitLen(BigInt(points.length));
|
|
2195
|
+
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1;
|
|
2196
|
+
const MASK = (1 << windowSize) - 1;
|
|
2197
|
+
const buckets = new Array(MASK + 1).fill(zero);
|
|
2198
|
+
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
|
2199
|
+
let sum = zero;
|
|
2200
|
+
for (let i = lastBits; i >= 0; i -= windowSize) {
|
|
2201
|
+
buckets.fill(zero);
|
|
2202
|
+
for (let j = 0; j < scalars.length; j++) {
|
|
2203
|
+
const scalar = scalars[j];
|
|
2204
|
+
const wbits2 = Number(scalar >> BigInt(i) & BigInt(MASK));
|
|
2205
|
+
buckets[wbits2] = buckets[wbits2].add(points[j]);
|
|
2206
|
+
}
|
|
2207
|
+
let resI = zero;
|
|
2208
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
|
2209
|
+
sumI = sumI.add(buckets[j]);
|
|
2210
|
+
resI = resI.add(sumI);
|
|
2211
|
+
}
|
|
2212
|
+
sum = sum.add(resI);
|
|
2213
|
+
if (i !== 0)
|
|
2214
|
+
for (let j = 0; j < windowSize; j++)
|
|
2215
|
+
sum = sum.double();
|
|
2216
|
+
}
|
|
2217
|
+
return sum;
|
|
2218
|
+
}
|
|
2219
|
+
function validateBasic(curve) {
|
|
2220
|
+
validateField(curve.Fp);
|
|
2221
|
+
validateObject(curve, {
|
|
2222
|
+
n: "bigint",
|
|
2223
|
+
h: "bigint",
|
|
2224
|
+
Gx: "field",
|
|
2225
|
+
Gy: "field"
|
|
2226
|
+
}, {
|
|
2227
|
+
nBitLength: "isSafeInteger",
|
|
2228
|
+
nByteLength: "isSafeInteger"
|
|
2229
|
+
});
|
|
2230
|
+
return Object.freeze({
|
|
2231
|
+
...nLength(curve.n, curve.nBitLength),
|
|
2232
|
+
...curve,
|
|
2233
|
+
...{ p: curve.Fp.ORDER }
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
// ../../node_modules/.pnpm/@noble+curves@1.7.0/node_modules/@noble/curves/esm/abstract/weierstrass.js
|
|
2238
|
+
function validateSigVerOpts(opts) {
|
|
2239
|
+
if (opts.lowS !== void 0)
|
|
2240
|
+
abool("lowS", opts.lowS);
|
|
2241
|
+
if (opts.prehash !== void 0)
|
|
2242
|
+
abool("prehash", opts.prehash);
|
|
2243
|
+
}
|
|
2244
|
+
function validatePointOpts(curve) {
|
|
2245
|
+
const opts = validateBasic(curve);
|
|
2246
|
+
validateObject(opts, {
|
|
2247
|
+
a: "field",
|
|
2248
|
+
b: "field"
|
|
2249
|
+
}, {
|
|
2250
|
+
allowedPrivateKeyLengths: "array",
|
|
2251
|
+
wrapPrivateKey: "boolean",
|
|
2252
|
+
isTorsionFree: "function",
|
|
2253
|
+
clearCofactor: "function",
|
|
2254
|
+
allowInfinityPoint: "boolean",
|
|
2255
|
+
fromBytes: "function",
|
|
2256
|
+
toBytes: "function"
|
|
2257
|
+
});
|
|
2258
|
+
const { endo, Fp, a } = opts;
|
|
2259
|
+
if (endo) {
|
|
2260
|
+
if (!Fp.eql(a, Fp.ZERO)) {
|
|
2261
|
+
throw new Error("invalid endomorphism, can only be defined for Koblitz curves that have a=0");
|
|
2262
|
+
}
|
|
2263
|
+
if (typeof endo !== "object" || typeof endo.beta !== "bigint" || typeof endo.splitScalar !== "function") {
|
|
2264
|
+
throw new Error("invalid endomorphism, expected beta: bigint and splitScalar: function");
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
return Object.freeze({ ...opts });
|
|
2268
|
+
}
|
|
2269
|
+
var { bytesToNumberBE: b2n, hexToBytes: h2b } = utils_exports;
|
|
2270
|
+
var DER = {
|
|
2271
|
+
// asn.1 DER encoding utils
|
|
2272
|
+
Err: class DERErr extends Error {
|
|
2273
|
+
constructor(m = "") {
|
|
2274
|
+
super(m);
|
|
2275
|
+
}
|
|
2276
|
+
},
|
|
2277
|
+
// Basic building block is TLV (Tag-Length-Value)
|
|
2278
|
+
_tlv: {
|
|
2279
|
+
encode: (tag, data) => {
|
|
2280
|
+
const { Err: E } = DER;
|
|
2281
|
+
if (tag < 0 || tag > 256)
|
|
2282
|
+
throw new E("tlv.encode: wrong tag");
|
|
2283
|
+
if (data.length & 1)
|
|
2284
|
+
throw new E("tlv.encode: unpadded data");
|
|
2285
|
+
const dataLen = data.length / 2;
|
|
2286
|
+
const len = numberToHexUnpadded(dataLen);
|
|
2287
|
+
if (len.length / 2 & 128)
|
|
2288
|
+
throw new E("tlv.encode: long form length too big");
|
|
2289
|
+
const lenLen = dataLen > 127 ? numberToHexUnpadded(len.length / 2 | 128) : "";
|
|
2290
|
+
const t = numberToHexUnpadded(tag);
|
|
2291
|
+
return t + lenLen + len + data;
|
|
2292
|
+
},
|
|
2293
|
+
// v - value, l - left bytes (unparsed)
|
|
2294
|
+
decode(tag, data) {
|
|
2295
|
+
const { Err: E } = DER;
|
|
2296
|
+
let pos = 0;
|
|
2297
|
+
if (tag < 0 || tag > 256)
|
|
2298
|
+
throw new E("tlv.encode: wrong tag");
|
|
2299
|
+
if (data.length < 2 || data[pos++] !== tag)
|
|
2300
|
+
throw new E("tlv.decode: wrong tlv");
|
|
2301
|
+
const first = data[pos++];
|
|
2302
|
+
const isLong = !!(first & 128);
|
|
2303
|
+
let length = 0;
|
|
2304
|
+
if (!isLong)
|
|
2305
|
+
length = first;
|
|
2306
|
+
else {
|
|
2307
|
+
const lenLen = first & 127;
|
|
2308
|
+
if (!lenLen)
|
|
2309
|
+
throw new E("tlv.decode(long): indefinite length not supported");
|
|
2310
|
+
if (lenLen > 4)
|
|
2311
|
+
throw new E("tlv.decode(long): byte length is too big");
|
|
2312
|
+
const lengthBytes = data.subarray(pos, pos + lenLen);
|
|
2313
|
+
if (lengthBytes.length !== lenLen)
|
|
2314
|
+
throw new E("tlv.decode: length bytes not complete");
|
|
2315
|
+
if (lengthBytes[0] === 0)
|
|
2316
|
+
throw new E("tlv.decode(long): zero leftmost byte");
|
|
2317
|
+
for (const b of lengthBytes)
|
|
2318
|
+
length = length << 8 | b;
|
|
2319
|
+
pos += lenLen;
|
|
2320
|
+
if (length < 128)
|
|
2321
|
+
throw new E("tlv.decode(long): not minimal encoding");
|
|
2322
|
+
}
|
|
2323
|
+
const v = data.subarray(pos, pos + length);
|
|
2324
|
+
if (v.length !== length)
|
|
2325
|
+
throw new E("tlv.decode: wrong value length");
|
|
2326
|
+
return { v, l: data.subarray(pos + length) };
|
|
2327
|
+
}
|
|
2328
|
+
},
|
|
2329
|
+
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
|
2330
|
+
// since we always use positive integers here. It must always be empty:
|
|
2331
|
+
// - add zero byte if exists
|
|
2332
|
+
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
2333
|
+
_int: {
|
|
2334
|
+
encode(num) {
|
|
2335
|
+
const { Err: E } = DER;
|
|
2336
|
+
if (num < _0n4)
|
|
2337
|
+
throw new E("integer: negative integers are not allowed");
|
|
2338
|
+
let hex = numberToHexUnpadded(num);
|
|
2339
|
+
if (Number.parseInt(hex[0], 16) & 8)
|
|
2340
|
+
hex = "00" + hex;
|
|
2341
|
+
if (hex.length & 1)
|
|
2342
|
+
throw new E("unexpected DER parsing assertion: unpadded hex");
|
|
2343
|
+
return hex;
|
|
2344
|
+
},
|
|
2345
|
+
decode(data) {
|
|
2346
|
+
const { Err: E } = DER;
|
|
2347
|
+
if (data[0] & 128)
|
|
2348
|
+
throw new E("invalid signature integer: negative");
|
|
2349
|
+
if (data[0] === 0 && !(data[1] & 128))
|
|
2350
|
+
throw new E("invalid signature integer: unnecessary leading zero");
|
|
2351
|
+
return b2n(data);
|
|
2352
|
+
}
|
|
2353
|
+
},
|
|
2354
|
+
toSig(hex) {
|
|
2355
|
+
const { Err: E, _int: int, _tlv: tlv } = DER;
|
|
2356
|
+
const data = typeof hex === "string" ? h2b(hex) : hex;
|
|
2357
|
+
abytes4(data);
|
|
2358
|
+
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(48, data);
|
|
2359
|
+
if (seqLeftBytes.length)
|
|
2360
|
+
throw new E("invalid signature: left bytes after parsing");
|
|
2361
|
+
const { v: rBytes, l: rLeftBytes } = tlv.decode(2, seqBytes);
|
|
2362
|
+
const { v: sBytes, l: sLeftBytes } = tlv.decode(2, rLeftBytes);
|
|
2363
|
+
if (sLeftBytes.length)
|
|
2364
|
+
throw new E("invalid signature: left bytes after parsing");
|
|
2365
|
+
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
|
2366
|
+
},
|
|
2367
|
+
hexFromSig(sig) {
|
|
2368
|
+
const { _tlv: tlv, _int: int } = DER;
|
|
2369
|
+
const rs = tlv.encode(2, int.encode(sig.r));
|
|
2370
|
+
const ss = tlv.encode(2, int.encode(sig.s));
|
|
2371
|
+
const seq = rs + ss;
|
|
2372
|
+
return tlv.encode(48, seq);
|
|
2373
|
+
}
|
|
2374
|
+
};
|
|
2375
|
+
var _0n4 = BigInt(0);
|
|
2376
|
+
var _1n4 = BigInt(1);
|
|
2377
|
+
var _2n3 = BigInt(2);
|
|
2378
|
+
var _3n2 = BigInt(3);
|
|
2379
|
+
var _4n2 = BigInt(4);
|
|
2380
|
+
function weierstrassPoints(opts) {
|
|
2381
|
+
const CURVE = validatePointOpts(opts);
|
|
2382
|
+
const { Fp } = CURVE;
|
|
2383
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
|
2384
|
+
const toBytes3 = CURVE.toBytes || ((_c, point, _isCompressed) => {
|
|
2385
|
+
const a = point.toAffine();
|
|
2386
|
+
return concatBytes3(Uint8Array.from([4]), Fp.toBytes(a.x), Fp.toBytes(a.y));
|
|
2387
|
+
});
|
|
2388
|
+
const fromBytes = CURVE.fromBytes || ((bytes) => {
|
|
2389
|
+
const tail = bytes.subarray(1);
|
|
2390
|
+
const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
|
2391
|
+
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
|
2392
|
+
return { x, y };
|
|
2393
|
+
});
|
|
2394
|
+
function weierstrassEquation(x) {
|
|
2395
|
+
const { a, b } = CURVE;
|
|
2396
|
+
const x2 = Fp.sqr(x);
|
|
2397
|
+
const x3 = Fp.mul(x2, x);
|
|
2398
|
+
return Fp.add(Fp.add(x3, Fp.mul(x, a)), b);
|
|
2399
|
+
}
|
|
2400
|
+
if (!Fp.eql(Fp.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx)))
|
|
2401
|
+
throw new Error("bad generator point: equation left != right");
|
|
2402
|
+
function isWithinCurveOrder(num) {
|
|
2403
|
+
return inRange(num, _1n4, CURVE.n);
|
|
2404
|
+
}
|
|
2405
|
+
function normPrivateKeyToScalar(key) {
|
|
2406
|
+
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N2 } = CURVE;
|
|
2407
|
+
if (lengths && typeof key !== "bigint") {
|
|
2408
|
+
if (isBytes4(key))
|
|
2409
|
+
key = bytesToHex2(key);
|
|
2410
|
+
if (typeof key !== "string" || !lengths.includes(key.length))
|
|
2411
|
+
throw new Error("invalid private key");
|
|
2412
|
+
key = key.padStart(nByteLength * 2, "0");
|
|
2413
|
+
}
|
|
2414
|
+
let num;
|
|
2415
|
+
try {
|
|
2416
|
+
num = typeof key === "bigint" ? key : bytesToNumberBE(ensureBytes("private key", key, nByteLength));
|
|
2417
|
+
} catch (error) {
|
|
2418
|
+
throw new Error("invalid private key, expected hex or " + nByteLength + " bytes, got " + typeof key);
|
|
2419
|
+
}
|
|
2420
|
+
if (wrapPrivateKey)
|
|
2421
|
+
num = mod(num, N2);
|
|
2422
|
+
aInRange("private key", num, _1n4, N2);
|
|
2423
|
+
return num;
|
|
2424
|
+
}
|
|
2425
|
+
function assertPrjPoint(other) {
|
|
2426
|
+
if (!(other instanceof Point2))
|
|
2427
|
+
throw new Error("ProjectivePoint expected");
|
|
2428
|
+
}
|
|
2429
|
+
const toAffineMemo = memoized((p, iz) => {
|
|
2430
|
+
const { px: x, py: y, pz: z } = p;
|
|
2431
|
+
if (Fp.eql(z, Fp.ONE))
|
|
2432
|
+
return { x, y };
|
|
2433
|
+
const is0 = p.is0();
|
|
2434
|
+
if (iz == null)
|
|
2435
|
+
iz = is0 ? Fp.ONE : Fp.inv(z);
|
|
2436
|
+
const ax = Fp.mul(x, iz);
|
|
2437
|
+
const ay = Fp.mul(y, iz);
|
|
2438
|
+
const zz = Fp.mul(z, iz);
|
|
2439
|
+
if (is0)
|
|
2440
|
+
return { x: Fp.ZERO, y: Fp.ZERO };
|
|
2441
|
+
if (!Fp.eql(zz, Fp.ONE))
|
|
2442
|
+
throw new Error("invZ was invalid");
|
|
2443
|
+
return { x: ax, y: ay };
|
|
2444
|
+
});
|
|
2445
|
+
const assertValidMemo = memoized((p) => {
|
|
2446
|
+
if (p.is0()) {
|
|
2447
|
+
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
|
2448
|
+
return;
|
|
2449
|
+
throw new Error("bad point: ZERO");
|
|
2450
|
+
}
|
|
2451
|
+
const { x, y } = p.toAffine();
|
|
2452
|
+
if (!Fp.isValid(x) || !Fp.isValid(y))
|
|
2453
|
+
throw new Error("bad point: x or y not FE");
|
|
2454
|
+
const left = Fp.sqr(y);
|
|
2455
|
+
const right = weierstrassEquation(x);
|
|
2456
|
+
if (!Fp.eql(left, right))
|
|
2457
|
+
throw new Error("bad point: equation left != right");
|
|
2458
|
+
if (!p.isTorsionFree())
|
|
2459
|
+
throw new Error("bad point: not in prime-order subgroup");
|
|
2460
|
+
return true;
|
|
2461
|
+
});
|
|
2462
|
+
class Point2 {
|
|
2463
|
+
constructor(px, py, pz) {
|
|
2464
|
+
this.px = px;
|
|
2465
|
+
this.py = py;
|
|
2466
|
+
this.pz = pz;
|
|
2467
|
+
if (px == null || !Fp.isValid(px))
|
|
2468
|
+
throw new Error("x required");
|
|
2469
|
+
if (py == null || !Fp.isValid(py))
|
|
2470
|
+
throw new Error("y required");
|
|
2471
|
+
if (pz == null || !Fp.isValid(pz))
|
|
2472
|
+
throw new Error("z required");
|
|
2473
|
+
Object.freeze(this);
|
|
2474
|
+
}
|
|
2475
|
+
// Does not validate if the point is on-curve.
|
|
2476
|
+
// Use fromHex instead, or call assertValidity() later.
|
|
2477
|
+
static fromAffine(p) {
|
|
2478
|
+
const { x, y } = p || {};
|
|
2479
|
+
if (!p || !Fp.isValid(x) || !Fp.isValid(y))
|
|
2480
|
+
throw new Error("invalid affine point");
|
|
2481
|
+
if (p instanceof Point2)
|
|
2482
|
+
throw new Error("projective point not allowed");
|
|
2483
|
+
const is0 = (i) => Fp.eql(i, Fp.ZERO);
|
|
2484
|
+
if (is0(x) && is0(y))
|
|
2485
|
+
return Point2.ZERO;
|
|
2486
|
+
return new Point2(x, y, Fp.ONE);
|
|
2487
|
+
}
|
|
2488
|
+
get x() {
|
|
2489
|
+
return this.toAffine().x;
|
|
2490
|
+
}
|
|
2491
|
+
get y() {
|
|
2492
|
+
return this.toAffine().y;
|
|
2493
|
+
}
|
|
2494
|
+
/**
|
|
2495
|
+
* Takes a bunch of Projective Points but executes only one
|
|
2496
|
+
* inversion on all of them. Inversion is very slow operation,
|
|
2497
|
+
* so this improves performance massively.
|
|
2498
|
+
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
|
2499
|
+
*/
|
|
2500
|
+
static normalizeZ(points) {
|
|
2501
|
+
const toInv = Fp.invertBatch(points.map((p) => p.pz));
|
|
2502
|
+
return points.map((p, i) => p.toAffine(toInv[i])).map(Point2.fromAffine);
|
|
2503
|
+
}
|
|
2504
|
+
/**
|
|
2505
|
+
* Converts hash string or Uint8Array to Point.
|
|
2506
|
+
* @param hex short/long ECDSA hex
|
|
2507
|
+
*/
|
|
2508
|
+
static fromHex(hex) {
|
|
2509
|
+
const P2 = Point2.fromAffine(fromBytes(ensureBytes("pointHex", hex)));
|
|
2510
|
+
P2.assertValidity();
|
|
2511
|
+
return P2;
|
|
2512
|
+
}
|
|
2513
|
+
// Multiplies generator point by privateKey.
|
|
2514
|
+
static fromPrivateKey(privateKey) {
|
|
2515
|
+
return Point2.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
|
2516
|
+
}
|
|
2517
|
+
// Multiscalar Multiplication
|
|
2518
|
+
static msm(points, scalars) {
|
|
2519
|
+
return pippenger(Point2, Fn, points, scalars);
|
|
2520
|
+
}
|
|
2521
|
+
// "Private method", don't use it directly
|
|
2522
|
+
_setWindowSize(windowSize) {
|
|
2523
|
+
wnaf.setWindowSize(this, windowSize);
|
|
2524
|
+
}
|
|
2525
|
+
// A point on curve is valid if it conforms to equation.
|
|
2526
|
+
assertValidity() {
|
|
2527
|
+
assertValidMemo(this);
|
|
2528
|
+
}
|
|
2529
|
+
hasEvenY() {
|
|
2530
|
+
const { y } = this.toAffine();
|
|
2531
|
+
if (Fp.isOdd)
|
|
2532
|
+
return !Fp.isOdd(y);
|
|
2533
|
+
throw new Error("Field doesn't support isOdd");
|
|
2534
|
+
}
|
|
2535
|
+
/**
|
|
2536
|
+
* Compare one point to another.
|
|
2537
|
+
*/
|
|
2538
|
+
equals(other) {
|
|
2539
|
+
assertPrjPoint(other);
|
|
2540
|
+
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
2541
|
+
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
2542
|
+
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
|
2543
|
+
const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
|
|
2544
|
+
return U1 && U2;
|
|
2545
|
+
}
|
|
2546
|
+
/**
|
|
2547
|
+
* Flips point to one corresponding to (x, -y) in Affine coordinates.
|
|
2548
|
+
*/
|
|
2549
|
+
negate() {
|
|
2550
|
+
return new Point2(this.px, Fp.neg(this.py), this.pz);
|
|
2551
|
+
}
|
|
2552
|
+
// Renes-Costello-Batina exception-free doubling formula.
|
|
2553
|
+
// There is 30% faster Jacobian formula, but it is not complete.
|
|
2554
|
+
// https://eprint.iacr.org/2015/1060, algorithm 3
|
|
2555
|
+
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
|
2556
|
+
double() {
|
|
2557
|
+
const { a, b } = CURVE;
|
|
2558
|
+
const b3 = Fp.mul(b, _3n2);
|
|
2559
|
+
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
2560
|
+
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO;
|
|
2561
|
+
let t0 = Fp.mul(X1, X1);
|
|
2562
|
+
let t1 = Fp.mul(Y1, Y1);
|
|
2563
|
+
let t2 = Fp.mul(Z1, Z1);
|
|
2564
|
+
let t3 = Fp.mul(X1, Y1);
|
|
2565
|
+
t3 = Fp.add(t3, t3);
|
|
2566
|
+
Z3 = Fp.mul(X1, Z1);
|
|
2567
|
+
Z3 = Fp.add(Z3, Z3);
|
|
2568
|
+
X3 = Fp.mul(a, Z3);
|
|
2569
|
+
Y3 = Fp.mul(b3, t2);
|
|
2570
|
+
Y3 = Fp.add(X3, Y3);
|
|
2571
|
+
X3 = Fp.sub(t1, Y3);
|
|
2572
|
+
Y3 = Fp.add(t1, Y3);
|
|
2573
|
+
Y3 = Fp.mul(X3, Y3);
|
|
2574
|
+
X3 = Fp.mul(t3, X3);
|
|
2575
|
+
Z3 = Fp.mul(b3, Z3);
|
|
2576
|
+
t2 = Fp.mul(a, t2);
|
|
2577
|
+
t3 = Fp.sub(t0, t2);
|
|
2578
|
+
t3 = Fp.mul(a, t3);
|
|
2579
|
+
t3 = Fp.add(t3, Z3);
|
|
2580
|
+
Z3 = Fp.add(t0, t0);
|
|
2581
|
+
t0 = Fp.add(Z3, t0);
|
|
2582
|
+
t0 = Fp.add(t0, t2);
|
|
2583
|
+
t0 = Fp.mul(t0, t3);
|
|
2584
|
+
Y3 = Fp.add(Y3, t0);
|
|
2585
|
+
t2 = Fp.mul(Y1, Z1);
|
|
2586
|
+
t2 = Fp.add(t2, t2);
|
|
2587
|
+
t0 = Fp.mul(t2, t3);
|
|
2588
|
+
X3 = Fp.sub(X3, t0);
|
|
2589
|
+
Z3 = Fp.mul(t2, t1);
|
|
2590
|
+
Z3 = Fp.add(Z3, Z3);
|
|
2591
|
+
Z3 = Fp.add(Z3, Z3);
|
|
2592
|
+
return new Point2(X3, Y3, Z3);
|
|
2593
|
+
}
|
|
2594
|
+
// Renes-Costello-Batina exception-free addition formula.
|
|
2595
|
+
// There is 30% faster Jacobian formula, but it is not complete.
|
|
2596
|
+
// https://eprint.iacr.org/2015/1060, algorithm 1
|
|
2597
|
+
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
|
2598
|
+
add(other) {
|
|
2599
|
+
assertPrjPoint(other);
|
|
2600
|
+
const { px: X1, py: Y1, pz: Z1 } = this;
|
|
2601
|
+
const { px: X2, py: Y2, pz: Z2 } = other;
|
|
2602
|
+
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO;
|
|
2603
|
+
const a = CURVE.a;
|
|
2604
|
+
const b3 = Fp.mul(CURVE.b, _3n2);
|
|
2605
|
+
let t0 = Fp.mul(X1, X2);
|
|
2606
|
+
let t1 = Fp.mul(Y1, Y2);
|
|
2607
|
+
let t2 = Fp.mul(Z1, Z2);
|
|
2608
|
+
let t3 = Fp.add(X1, Y1);
|
|
2609
|
+
let t4 = Fp.add(X2, Y2);
|
|
2610
|
+
t3 = Fp.mul(t3, t4);
|
|
2611
|
+
t4 = Fp.add(t0, t1);
|
|
2612
|
+
t3 = Fp.sub(t3, t4);
|
|
2613
|
+
t4 = Fp.add(X1, Z1);
|
|
2614
|
+
let t5 = Fp.add(X2, Z2);
|
|
2615
|
+
t4 = Fp.mul(t4, t5);
|
|
2616
|
+
t5 = Fp.add(t0, t2);
|
|
2617
|
+
t4 = Fp.sub(t4, t5);
|
|
2618
|
+
t5 = Fp.add(Y1, Z1);
|
|
2619
|
+
X3 = Fp.add(Y2, Z2);
|
|
2620
|
+
t5 = Fp.mul(t5, X3);
|
|
2621
|
+
X3 = Fp.add(t1, t2);
|
|
2622
|
+
t5 = Fp.sub(t5, X3);
|
|
2623
|
+
Z3 = Fp.mul(a, t4);
|
|
2624
|
+
X3 = Fp.mul(b3, t2);
|
|
2625
|
+
Z3 = Fp.add(X3, Z3);
|
|
2626
|
+
X3 = Fp.sub(t1, Z3);
|
|
2627
|
+
Z3 = Fp.add(t1, Z3);
|
|
2628
|
+
Y3 = Fp.mul(X3, Z3);
|
|
2629
|
+
t1 = Fp.add(t0, t0);
|
|
2630
|
+
t1 = Fp.add(t1, t0);
|
|
2631
|
+
t2 = Fp.mul(a, t2);
|
|
2632
|
+
t4 = Fp.mul(b3, t4);
|
|
2633
|
+
t1 = Fp.add(t1, t2);
|
|
2634
|
+
t2 = Fp.sub(t0, t2);
|
|
2635
|
+
t2 = Fp.mul(a, t2);
|
|
2636
|
+
t4 = Fp.add(t4, t2);
|
|
2637
|
+
t0 = Fp.mul(t1, t4);
|
|
2638
|
+
Y3 = Fp.add(Y3, t0);
|
|
2639
|
+
t0 = Fp.mul(t5, t4);
|
|
2640
|
+
X3 = Fp.mul(t3, X3);
|
|
2641
|
+
X3 = Fp.sub(X3, t0);
|
|
2642
|
+
t0 = Fp.mul(t3, t1);
|
|
2643
|
+
Z3 = Fp.mul(t5, Z3);
|
|
2644
|
+
Z3 = Fp.add(Z3, t0);
|
|
2645
|
+
return new Point2(X3, Y3, Z3);
|
|
2646
|
+
}
|
|
2647
|
+
subtract(other) {
|
|
2648
|
+
return this.add(other.negate());
|
|
2649
|
+
}
|
|
2650
|
+
is0() {
|
|
2651
|
+
return this.equals(Point2.ZERO);
|
|
2652
|
+
}
|
|
2653
|
+
wNAF(n) {
|
|
2654
|
+
return wnaf.wNAFCached(this, n, Point2.normalizeZ);
|
|
2655
|
+
}
|
|
2656
|
+
/**
|
|
2657
|
+
* Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
2658
|
+
* It's faster, but should only be used when you don't care about
|
|
2659
|
+
* an exposed private key e.g. sig verification, which works over *public* keys.
|
|
2660
|
+
*/
|
|
2661
|
+
multiplyUnsafe(sc) {
|
|
2662
|
+
const { endo, n: N2 } = CURVE;
|
|
2663
|
+
aInRange("scalar", sc, _0n4, N2);
|
|
2664
|
+
const I2 = Point2.ZERO;
|
|
2665
|
+
if (sc === _0n4)
|
|
2666
|
+
return I2;
|
|
2667
|
+
if (this.is0() || sc === _1n4)
|
|
2668
|
+
return this;
|
|
2669
|
+
if (!endo || wnaf.hasPrecomputes(this))
|
|
2670
|
+
return wnaf.wNAFCachedUnsafe(this, sc, Point2.normalizeZ);
|
|
2671
|
+
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
|
2672
|
+
let k1p = I2;
|
|
2673
|
+
let k2p = I2;
|
|
2674
|
+
let d = this;
|
|
2675
|
+
while (k1 > _0n4 || k2 > _0n4) {
|
|
2676
|
+
if (k1 & _1n4)
|
|
2677
|
+
k1p = k1p.add(d);
|
|
2678
|
+
if (k2 & _1n4)
|
|
2679
|
+
k2p = k2p.add(d);
|
|
2680
|
+
d = d.double();
|
|
2681
|
+
k1 >>= _1n4;
|
|
2682
|
+
k2 >>= _1n4;
|
|
2683
|
+
}
|
|
2684
|
+
if (k1neg)
|
|
2685
|
+
k1p = k1p.negate();
|
|
2686
|
+
if (k2neg)
|
|
2687
|
+
k2p = k2p.negate();
|
|
2688
|
+
k2p = new Point2(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
|
|
2689
|
+
return k1p.add(k2p);
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Constant time multiplication.
|
|
2693
|
+
* Uses wNAF method. Windowed method may be 10% faster,
|
|
2694
|
+
* but takes 2x longer to generate and consumes 2x memory.
|
|
2695
|
+
* Uses precomputes when available.
|
|
2696
|
+
* Uses endomorphism for Koblitz curves.
|
|
2697
|
+
* @param scalar by which the point would be multiplied
|
|
2698
|
+
* @returns New point
|
|
2699
|
+
*/
|
|
2700
|
+
multiply(scalar) {
|
|
2701
|
+
const { endo, n: N2 } = CURVE;
|
|
2702
|
+
aInRange("scalar", scalar, _1n4, N2);
|
|
2703
|
+
let point, fake;
|
|
2704
|
+
if (endo) {
|
|
2705
|
+
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
|
|
2706
|
+
let { p: k1p, f: f1p } = this.wNAF(k1);
|
|
2707
|
+
let { p: k2p, f: f2p } = this.wNAF(k2);
|
|
2708
|
+
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
|
2709
|
+
k2p = wnaf.constTimeNegate(k2neg, k2p);
|
|
2710
|
+
k2p = new Point2(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
|
|
2711
|
+
point = k1p.add(k2p);
|
|
2712
|
+
fake = f1p.add(f2p);
|
|
2713
|
+
} else {
|
|
2714
|
+
const { p, f } = this.wNAF(scalar);
|
|
2715
|
+
point = p;
|
|
2716
|
+
fake = f;
|
|
2717
|
+
}
|
|
2718
|
+
return Point2.normalizeZ([point, fake])[0];
|
|
2719
|
+
}
|
|
2720
|
+
/**
|
|
2721
|
+
* Efficiently calculate `aP + bQ`. Unsafe, can expose private key, if used incorrectly.
|
|
2722
|
+
* Not using Strauss-Shamir trick: precomputation tables are faster.
|
|
2723
|
+
* The trick could be useful if both P and Q are not G (not in our case).
|
|
2724
|
+
* @returns non-zero affine point
|
|
2725
|
+
*/
|
|
2726
|
+
multiplyAndAddUnsafe(Q, a, b) {
|
|
2727
|
+
const G2 = Point2.BASE;
|
|
2728
|
+
const mul = (P2, a2) => a2 === _0n4 || a2 === _1n4 || !P2.equals(G2) ? P2.multiplyUnsafe(a2) : P2.multiply(a2);
|
|
2729
|
+
const sum = mul(this, a).add(mul(Q, b));
|
|
2730
|
+
return sum.is0() ? void 0 : sum;
|
|
2731
|
+
}
|
|
2732
|
+
// Converts Projective point to affine (x, y) coordinates.
|
|
2733
|
+
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
2734
|
+
// (x, y, z) ∋ (x=x/z, y=y/z)
|
|
2735
|
+
toAffine(iz) {
|
|
2736
|
+
return toAffineMemo(this, iz);
|
|
2737
|
+
}
|
|
2738
|
+
isTorsionFree() {
|
|
2739
|
+
const { h: cofactor, isTorsionFree } = CURVE;
|
|
2740
|
+
if (cofactor === _1n4)
|
|
2741
|
+
return true;
|
|
2742
|
+
if (isTorsionFree)
|
|
2743
|
+
return isTorsionFree(Point2, this);
|
|
2744
|
+
throw new Error("isTorsionFree() has not been declared for the elliptic curve");
|
|
2745
|
+
}
|
|
2746
|
+
clearCofactor() {
|
|
2747
|
+
const { h: cofactor, clearCofactor } = CURVE;
|
|
2748
|
+
if (cofactor === _1n4)
|
|
2749
|
+
return this;
|
|
2750
|
+
if (clearCofactor)
|
|
2751
|
+
return clearCofactor(Point2, this);
|
|
2752
|
+
return this.multiplyUnsafe(CURVE.h);
|
|
2753
|
+
}
|
|
2754
|
+
toRawBytes(isCompressed = true) {
|
|
2755
|
+
abool("isCompressed", isCompressed);
|
|
2756
|
+
this.assertValidity();
|
|
2757
|
+
return toBytes3(Point2, this, isCompressed);
|
|
2758
|
+
}
|
|
2759
|
+
toHex(isCompressed = true) {
|
|
2760
|
+
abool("isCompressed", isCompressed);
|
|
2761
|
+
return bytesToHex2(this.toRawBytes(isCompressed));
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
Point2.BASE = new Point2(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
|
2765
|
+
Point2.ZERO = new Point2(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
|
2766
|
+
const _bits = CURVE.nBitLength;
|
|
2767
|
+
const wnaf = wNAF2(Point2, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
|
2768
|
+
return {
|
|
2769
|
+
CURVE,
|
|
2770
|
+
ProjectivePoint: Point2,
|
|
2771
|
+
normPrivateKeyToScalar,
|
|
2772
|
+
weierstrassEquation,
|
|
2773
|
+
isWithinCurveOrder
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
function validateOpts(curve) {
|
|
2777
|
+
const opts = validateBasic(curve);
|
|
2778
|
+
validateObject(opts, {
|
|
2779
|
+
hash: "hash",
|
|
2780
|
+
hmac: "function",
|
|
2781
|
+
randomBytes: "function"
|
|
2782
|
+
}, {
|
|
2783
|
+
bits2int: "function",
|
|
2784
|
+
bits2int_modN: "function",
|
|
2785
|
+
lowS: "boolean"
|
|
2786
|
+
});
|
|
2787
|
+
return Object.freeze({ lowS: true, ...opts });
|
|
2788
|
+
}
|
|
2789
|
+
function weierstrass(curveDef) {
|
|
2790
|
+
const CURVE = validateOpts(curveDef);
|
|
2791
|
+
const { Fp, n: CURVE_ORDER } = CURVE;
|
|
2792
|
+
const compressedLen = Fp.BYTES + 1;
|
|
2793
|
+
const uncompressedLen = 2 * Fp.BYTES + 1;
|
|
2794
|
+
function modN2(a) {
|
|
2795
|
+
return mod(a, CURVE_ORDER);
|
|
2796
|
+
}
|
|
2797
|
+
function invN(a) {
|
|
2798
|
+
return invert2(a, CURVE_ORDER);
|
|
2799
|
+
}
|
|
2800
|
+
const { ProjectivePoint: Point2, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder } = weierstrassPoints({
|
|
2801
|
+
...CURVE,
|
|
2802
|
+
toBytes(_c, point, isCompressed) {
|
|
2803
|
+
const a = point.toAffine();
|
|
2804
|
+
const x = Fp.toBytes(a.x);
|
|
2805
|
+
const cat = concatBytes3;
|
|
2806
|
+
abool("isCompressed", isCompressed);
|
|
2807
|
+
if (isCompressed) {
|
|
2808
|
+
return cat(Uint8Array.from([point.hasEvenY() ? 2 : 3]), x);
|
|
2809
|
+
} else {
|
|
2810
|
+
return cat(Uint8Array.from([4]), x, Fp.toBytes(a.y));
|
|
2811
|
+
}
|
|
2812
|
+
},
|
|
2813
|
+
fromBytes(bytes) {
|
|
2814
|
+
const len = bytes.length;
|
|
2815
|
+
const head = bytes[0];
|
|
2816
|
+
const tail = bytes.subarray(1);
|
|
2817
|
+
if (len === compressedLen && (head === 2 || head === 3)) {
|
|
2818
|
+
const x = bytesToNumberBE(tail);
|
|
2819
|
+
if (!inRange(x, _1n4, Fp.ORDER))
|
|
2820
|
+
throw new Error("Point is not on curve");
|
|
2821
|
+
const y2 = weierstrassEquation(x);
|
|
2822
|
+
let y;
|
|
2823
|
+
try {
|
|
2824
|
+
y = Fp.sqrt(y2);
|
|
2825
|
+
} catch (sqrtError) {
|
|
2826
|
+
const suffix = sqrtError instanceof Error ? ": " + sqrtError.message : "";
|
|
2827
|
+
throw new Error("Point is not on curve" + suffix);
|
|
2828
|
+
}
|
|
2829
|
+
const isYOdd = (y & _1n4) === _1n4;
|
|
2830
|
+
const isHeadOdd = (head & 1) === 1;
|
|
2831
|
+
if (isHeadOdd !== isYOdd)
|
|
2832
|
+
y = Fp.neg(y);
|
|
2833
|
+
return { x, y };
|
|
2834
|
+
} else if (len === uncompressedLen && head === 4) {
|
|
2835
|
+
const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
|
2836
|
+
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
|
2837
|
+
return { x, y };
|
|
2838
|
+
} else {
|
|
2839
|
+
const cl = compressedLen;
|
|
2840
|
+
const ul = uncompressedLen;
|
|
2841
|
+
throw new Error("invalid Point, expected length of " + cl + ", or uncompressed " + ul + ", got " + len);
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
});
|
|
2845
|
+
const numToNByteStr = (num) => bytesToHex2(numberToBytesBE(num, CURVE.nByteLength));
|
|
2846
|
+
function isBiggerThanHalfOrder(number) {
|
|
2847
|
+
const HALF = CURVE_ORDER >> _1n4;
|
|
2848
|
+
return number > HALF;
|
|
2849
|
+
}
|
|
2850
|
+
function normalizeS(s) {
|
|
2851
|
+
return isBiggerThanHalfOrder(s) ? modN2(-s) : s;
|
|
2852
|
+
}
|
|
2853
|
+
const slcNum = (b, from, to) => bytesToNumberBE(b.slice(from, to));
|
|
2854
|
+
class Signature {
|
|
2855
|
+
constructor(r, s, recovery) {
|
|
2856
|
+
this.r = r;
|
|
2857
|
+
this.s = s;
|
|
2858
|
+
this.recovery = recovery;
|
|
2859
|
+
this.assertValidity();
|
|
2860
|
+
}
|
|
2861
|
+
// pair (bytes of r, bytes of s)
|
|
2862
|
+
static fromCompact(hex) {
|
|
2863
|
+
const l = CURVE.nByteLength;
|
|
2864
|
+
hex = ensureBytes("compactSignature", hex, l * 2);
|
|
2865
|
+
return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
|
|
2866
|
+
}
|
|
2867
|
+
// DER encoded ECDSA signature
|
|
2868
|
+
// https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
|
|
2869
|
+
static fromDER(hex) {
|
|
2870
|
+
const { r, s } = DER.toSig(ensureBytes("DER", hex));
|
|
2871
|
+
return new Signature(r, s);
|
|
2872
|
+
}
|
|
2873
|
+
assertValidity() {
|
|
2874
|
+
aInRange("r", this.r, _1n4, CURVE_ORDER);
|
|
2875
|
+
aInRange("s", this.s, _1n4, CURVE_ORDER);
|
|
2876
|
+
}
|
|
2877
|
+
addRecoveryBit(recovery) {
|
|
2878
|
+
return new Signature(this.r, this.s, recovery);
|
|
2879
|
+
}
|
|
2880
|
+
recoverPublicKey(msgHash) {
|
|
2881
|
+
const { r, s, recovery: rec } = this;
|
|
2882
|
+
const h2 = bits2int_modN(ensureBytes("msgHash", msgHash));
|
|
2883
|
+
if (rec == null || ![0, 1, 2, 3].includes(rec))
|
|
2884
|
+
throw new Error("recovery id invalid");
|
|
2885
|
+
const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
|
|
2886
|
+
if (radj >= Fp.ORDER)
|
|
2887
|
+
throw new Error("recovery id 2 or 3 invalid");
|
|
2888
|
+
const prefix = (rec & 1) === 0 ? "02" : "03";
|
|
2889
|
+
const R = Point2.fromHex(prefix + numToNByteStr(radj));
|
|
2890
|
+
const ir = invN(radj);
|
|
2891
|
+
const u1 = modN2(-h2 * ir);
|
|
2892
|
+
const u2 = modN2(s * ir);
|
|
2893
|
+
const Q = Point2.BASE.multiplyAndAddUnsafe(R, u1, u2);
|
|
2894
|
+
if (!Q)
|
|
2895
|
+
throw new Error("point at infinify");
|
|
2896
|
+
Q.assertValidity();
|
|
2897
|
+
return Q;
|
|
2898
|
+
}
|
|
2899
|
+
// Signatures should be low-s, to prevent malleability.
|
|
2900
|
+
hasHighS() {
|
|
2901
|
+
return isBiggerThanHalfOrder(this.s);
|
|
2902
|
+
}
|
|
2903
|
+
normalizeS() {
|
|
2904
|
+
return this.hasHighS() ? new Signature(this.r, modN2(-this.s), this.recovery) : this;
|
|
2905
|
+
}
|
|
2906
|
+
// DER-encoded
|
|
2907
|
+
toDERRawBytes() {
|
|
2908
|
+
return hexToBytes2(this.toDERHex());
|
|
2909
|
+
}
|
|
2910
|
+
toDERHex() {
|
|
2911
|
+
return DER.hexFromSig({ r: this.r, s: this.s });
|
|
2912
|
+
}
|
|
2913
|
+
// padded bytes of r, then padded bytes of s
|
|
2914
|
+
toCompactRawBytes() {
|
|
2915
|
+
return hexToBytes2(this.toCompactHex());
|
|
2916
|
+
}
|
|
2917
|
+
toCompactHex() {
|
|
2918
|
+
return numToNByteStr(this.r) + numToNByteStr(this.s);
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
const utils = {
|
|
2922
|
+
isValidPrivateKey(privateKey) {
|
|
2923
|
+
try {
|
|
2924
|
+
normPrivateKeyToScalar(privateKey);
|
|
2925
|
+
return true;
|
|
2926
|
+
} catch (error) {
|
|
2927
|
+
return false;
|
|
2928
|
+
}
|
|
2929
|
+
},
|
|
2930
|
+
normPrivateKeyToScalar,
|
|
2931
|
+
/**
|
|
2932
|
+
* Produces cryptographically secure private key from random of size
|
|
2933
|
+
* (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
|
|
2934
|
+
*/
|
|
2935
|
+
randomPrivateKey: () => {
|
|
2936
|
+
const length = getMinHashLength(CURVE.n);
|
|
2937
|
+
return mapHashToField(CURVE.randomBytes(length), CURVE.n);
|
|
2938
|
+
},
|
|
2939
|
+
/**
|
|
2940
|
+
* Creates precompute table for an arbitrary EC point. Makes point "cached".
|
|
2941
|
+
* Allows to massively speed-up `point.multiply(scalar)`.
|
|
2942
|
+
* @returns cached point
|
|
2943
|
+
* @example
|
|
2944
|
+
* const fast = utils.precompute(8, ProjectivePoint.fromHex(someonesPubKey));
|
|
2945
|
+
* fast.multiply(privKey); // much faster ECDH now
|
|
2946
|
+
*/
|
|
2947
|
+
precompute(windowSize = 8, point = Point2.BASE) {
|
|
2948
|
+
point._setWindowSize(windowSize);
|
|
2949
|
+
point.multiply(BigInt(3));
|
|
2950
|
+
return point;
|
|
2951
|
+
}
|
|
2952
|
+
};
|
|
2953
|
+
function getPublicKey(privateKey, isCompressed = true) {
|
|
2954
|
+
return Point2.fromPrivateKey(privateKey).toRawBytes(isCompressed);
|
|
2955
|
+
}
|
|
2956
|
+
function isProbPub(item) {
|
|
2957
|
+
const arr = isBytes4(item);
|
|
2958
|
+
const str = typeof item === "string";
|
|
2959
|
+
const len = (arr || str) && item.length;
|
|
2960
|
+
if (arr)
|
|
2961
|
+
return len === compressedLen || len === uncompressedLen;
|
|
2962
|
+
if (str)
|
|
2963
|
+
return len === 2 * compressedLen || len === 2 * uncompressedLen;
|
|
2964
|
+
if (item instanceof Point2)
|
|
2965
|
+
return true;
|
|
2966
|
+
return false;
|
|
2967
|
+
}
|
|
2968
|
+
function getSharedSecret(privateA, publicB, isCompressed = true) {
|
|
2969
|
+
if (isProbPub(privateA))
|
|
2970
|
+
throw new Error("first arg must be private key");
|
|
2971
|
+
if (!isProbPub(publicB))
|
|
2972
|
+
throw new Error("second arg must be public key");
|
|
2973
|
+
const b = Point2.fromHex(publicB);
|
|
2974
|
+
return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed);
|
|
2975
|
+
}
|
|
2976
|
+
const bits2int = CURVE.bits2int || function(bytes) {
|
|
2977
|
+
if (bytes.length > 8192)
|
|
2978
|
+
throw new Error("input is too large");
|
|
2979
|
+
const num = bytesToNumberBE(bytes);
|
|
2980
|
+
const delta = bytes.length * 8 - CURVE.nBitLength;
|
|
2981
|
+
return delta > 0 ? num >> BigInt(delta) : num;
|
|
2982
|
+
};
|
|
2983
|
+
const bits2int_modN = CURVE.bits2int_modN || function(bytes) {
|
|
2984
|
+
return modN2(bits2int(bytes));
|
|
2985
|
+
};
|
|
2986
|
+
const ORDER_MASK = bitMask(CURVE.nBitLength);
|
|
2987
|
+
function int2octets(num) {
|
|
2988
|
+
aInRange("num < 2^" + CURVE.nBitLength, num, _0n4, ORDER_MASK);
|
|
2989
|
+
return numberToBytesBE(num, CURVE.nByteLength);
|
|
2990
|
+
}
|
|
2991
|
+
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
|
2992
|
+
if (["recovered", "canonical"].some((k) => k in opts))
|
|
2993
|
+
throw new Error("sign() legacy options not supported");
|
|
2994
|
+
const { hash: hash2, randomBytes: randomBytes3 } = CURVE;
|
|
2995
|
+
let { lowS, prehash, extraEntropy: ent } = opts;
|
|
2996
|
+
if (lowS == null)
|
|
2997
|
+
lowS = true;
|
|
2998
|
+
msgHash = ensureBytes("msgHash", msgHash);
|
|
2999
|
+
validateSigVerOpts(opts);
|
|
3000
|
+
if (prehash)
|
|
3001
|
+
msgHash = ensureBytes("prehashed msgHash", hash2(msgHash));
|
|
3002
|
+
const h1int = bits2int_modN(msgHash);
|
|
3003
|
+
const d = normPrivateKeyToScalar(privateKey);
|
|
3004
|
+
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
3005
|
+
if (ent != null && ent !== false) {
|
|
3006
|
+
const e = ent === true ? randomBytes3(Fp.BYTES) : ent;
|
|
3007
|
+
seedArgs.push(ensureBytes("extraEntropy", e));
|
|
3008
|
+
}
|
|
3009
|
+
const seed = concatBytes3(...seedArgs);
|
|
3010
|
+
const m = h1int;
|
|
3011
|
+
function k2sig(kBytes) {
|
|
3012
|
+
const k = bits2int(kBytes);
|
|
3013
|
+
if (!isWithinCurveOrder(k))
|
|
3014
|
+
return;
|
|
3015
|
+
const ik = invN(k);
|
|
3016
|
+
const q = Point2.BASE.multiply(k).toAffine();
|
|
3017
|
+
const r = modN2(q.x);
|
|
3018
|
+
if (r === _0n4)
|
|
3019
|
+
return;
|
|
3020
|
+
const s = modN2(ik * modN2(m + r * d));
|
|
3021
|
+
if (s === _0n4)
|
|
3022
|
+
return;
|
|
3023
|
+
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n4);
|
|
3024
|
+
let normS = s;
|
|
3025
|
+
if (lowS && isBiggerThanHalfOrder(s)) {
|
|
3026
|
+
normS = normalizeS(s);
|
|
3027
|
+
recovery ^= 1;
|
|
3028
|
+
}
|
|
3029
|
+
return new Signature(r, normS, recovery);
|
|
3030
|
+
}
|
|
3031
|
+
return { seed, k2sig };
|
|
3032
|
+
}
|
|
3033
|
+
const defaultSigOpts = { lowS: CURVE.lowS, prehash: false };
|
|
3034
|
+
const defaultVerOpts = { lowS: CURVE.lowS, prehash: false };
|
|
3035
|
+
function sign(msgHash, privKey, opts = defaultSigOpts) {
|
|
3036
|
+
const { seed, k2sig } = prepSig(msgHash, privKey, opts);
|
|
3037
|
+
const C2 = CURVE;
|
|
3038
|
+
const drbg = createHmacDrbg(C2.hash.outputLen, C2.nByteLength, C2.hmac);
|
|
3039
|
+
return drbg(seed, k2sig);
|
|
3040
|
+
}
|
|
3041
|
+
Point2.BASE._setWindowSize(8);
|
|
3042
|
+
function verify2(signature, msgHash, publicKey, opts = defaultVerOpts) {
|
|
3043
|
+
const sg = signature;
|
|
3044
|
+
msgHash = ensureBytes("msgHash", msgHash);
|
|
3045
|
+
publicKey = ensureBytes("publicKey", publicKey);
|
|
3046
|
+
const { lowS, prehash, format } = opts;
|
|
3047
|
+
validateSigVerOpts(opts);
|
|
3048
|
+
if ("strict" in opts)
|
|
3049
|
+
throw new Error("options.strict was renamed to lowS");
|
|
3050
|
+
if (format !== void 0 && format !== "compact" && format !== "der")
|
|
3051
|
+
throw new Error("format must be compact or der");
|
|
3052
|
+
const isHex = typeof sg === "string" || isBytes4(sg);
|
|
3053
|
+
const isObj = !isHex && !format && typeof sg === "object" && sg !== null && typeof sg.r === "bigint" && typeof sg.s === "bigint";
|
|
3054
|
+
if (!isHex && !isObj)
|
|
3055
|
+
throw new Error("invalid signature, expected Uint8Array, hex string or Signature instance");
|
|
3056
|
+
let _sig = void 0;
|
|
3057
|
+
let P2;
|
|
3058
|
+
try {
|
|
3059
|
+
if (isObj)
|
|
3060
|
+
_sig = new Signature(sg.r, sg.s);
|
|
3061
|
+
if (isHex) {
|
|
3062
|
+
try {
|
|
3063
|
+
if (format !== "compact")
|
|
3064
|
+
_sig = Signature.fromDER(sg);
|
|
3065
|
+
} catch (derError) {
|
|
3066
|
+
if (!(derError instanceof DER.Err))
|
|
3067
|
+
throw derError;
|
|
3068
|
+
}
|
|
3069
|
+
if (!_sig && format !== "der")
|
|
3070
|
+
_sig = Signature.fromCompact(sg);
|
|
3071
|
+
}
|
|
3072
|
+
P2 = Point2.fromHex(publicKey);
|
|
3073
|
+
} catch (error) {
|
|
3074
|
+
return false;
|
|
3075
|
+
}
|
|
3076
|
+
if (!_sig)
|
|
3077
|
+
return false;
|
|
3078
|
+
if (lowS && _sig.hasHighS())
|
|
3079
|
+
return false;
|
|
3080
|
+
if (prehash)
|
|
3081
|
+
msgHash = CURVE.hash(msgHash);
|
|
3082
|
+
const { r, s } = _sig;
|
|
3083
|
+
const h2 = bits2int_modN(msgHash);
|
|
3084
|
+
const is = invN(s);
|
|
3085
|
+
const u1 = modN2(h2 * is);
|
|
3086
|
+
const u2 = modN2(r * is);
|
|
3087
|
+
const R = Point2.BASE.multiplyAndAddUnsafe(P2, u1, u2)?.toAffine();
|
|
3088
|
+
if (!R)
|
|
3089
|
+
return false;
|
|
3090
|
+
const v = modN2(R.x);
|
|
3091
|
+
return v === r;
|
|
3092
|
+
}
|
|
3093
|
+
return {
|
|
3094
|
+
CURVE,
|
|
3095
|
+
getPublicKey,
|
|
3096
|
+
getSharedSecret,
|
|
3097
|
+
sign,
|
|
3098
|
+
verify: verify2,
|
|
3099
|
+
ProjectivePoint: Point2,
|
|
3100
|
+
Signature,
|
|
3101
|
+
utils
|
|
3102
|
+
};
|
|
3103
|
+
}
|
|
3104
|
+
|
|
3105
|
+
// ../../node_modules/.pnpm/@noble+curves@1.7.0/node_modules/@noble/curves/esm/_shortw_utils.js
|
|
3106
|
+
function getHash(hash2) {
|
|
3107
|
+
return {
|
|
3108
|
+
hash: hash2,
|
|
3109
|
+
hmac: (key, ...msgs) => hmac(hash2, key, concatBytes2(...msgs)),
|
|
3110
|
+
randomBytes: randomBytes2
|
|
3111
|
+
};
|
|
3112
|
+
}
|
|
3113
|
+
function createCurve(curveDef, defHash) {
|
|
3114
|
+
const create = (hash2) => weierstrass({ ...curveDef, ...getHash(hash2) });
|
|
3115
|
+
return Object.freeze({ ...create(defHash), create });
|
|
3116
|
+
}
|
|
3117
|
+
|
|
3118
|
+
// ../../node_modules/.pnpm/@noble+curves@1.7.0/node_modules/@noble/curves/esm/p256.js
|
|
3119
|
+
var Fp256 = Field(BigInt("0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"));
|
|
3120
|
+
var CURVE_A = Fp256.create(BigInt("-3"));
|
|
3121
|
+
var CURVE_B = BigInt("0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b");
|
|
3122
|
+
var p256 = createCurve({
|
|
3123
|
+
a: CURVE_A,
|
|
3124
|
+
// Equation params: a, b
|
|
3125
|
+
b: CURVE_B,
|
|
3126
|
+
Fp: Fp256,
|
|
3127
|
+
// Field: 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
|
|
3128
|
+
// Curve order, total count of valid points in the field
|
|
3129
|
+
n: BigInt("0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"),
|
|
3130
|
+
// Base (generator) point (x, y)
|
|
3131
|
+
Gx: BigInt("0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"),
|
|
3132
|
+
Gy: BigInt("0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"),
|
|
3133
|
+
h: BigInt(1),
|
|
3134
|
+
lowS: false
|
|
3135
|
+
}, sha2562);
|
|
3136
|
+
|
|
3137
|
+
// src/suite-dispatch.ts
|
|
3138
|
+
if (!hashes.sha512) {
|
|
3139
|
+
hashes.sha512 = (msg) => sha512(msg);
|
|
3140
|
+
}
|
|
3141
|
+
async function verifyBySuite(suite, canonicalBytes, signatureBytes, publicKeyBytes) {
|
|
3142
|
+
switch (suite) {
|
|
3143
|
+
case "motebit-jcs-ed25519-b64-v1":
|
|
3144
|
+
case "motebit-jcs-ed25519-hex-v1":
|
|
3145
|
+
case "motebit-jwt-ed25519-v1":
|
|
3146
|
+
case "motebit-concat-ed25519-hex-v1":
|
|
3147
|
+
case "eddsa-jcs-2022":
|
|
3148
|
+
try {
|
|
3149
|
+
return await verifyAsync(signatureBytes, canonicalBytes, publicKeyBytes);
|
|
3150
|
+
} catch {
|
|
3151
|
+
return false;
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
async function signBySuite(suite, canonicalBytes, privateKeyBytes) {
|
|
3156
|
+
switch (suite) {
|
|
3157
|
+
case "motebit-jcs-ed25519-b64-v1":
|
|
3158
|
+
case "motebit-jcs-ed25519-hex-v1":
|
|
3159
|
+
case "motebit-jwt-ed25519-v1":
|
|
3160
|
+
case "motebit-concat-ed25519-hex-v1":
|
|
3161
|
+
case "eddsa-jcs-2022":
|
|
3162
|
+
return signAsync(canonicalBytes, privateKeyBytes);
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
async function ed25519Sign(message, privateKey) {
|
|
3166
|
+
return signAsync(message, privateKey);
|
|
3167
|
+
}
|
|
3168
|
+
async function ed25519Verify(signature, message, publicKey) {
|
|
3169
|
+
try {
|
|
3170
|
+
return await verifyAsync(signature, message, publicKey);
|
|
3171
|
+
} catch {
|
|
3172
|
+
return false;
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
async function generateEd25519Keypair() {
|
|
3176
|
+
const { secretKey, publicKey } = await keygenAsync();
|
|
3177
|
+
return { publicKey, privateKey: secretKey };
|
|
3178
|
+
}
|
|
3179
|
+
async function getPublicKeyBySuite(privateKey, suite) {
|
|
3180
|
+
switch (suite) {
|
|
3181
|
+
case "motebit-jcs-ed25519-b64-v1":
|
|
3182
|
+
case "motebit-jcs-ed25519-hex-v1":
|
|
3183
|
+
case "motebit-jwt-ed25519-v1":
|
|
3184
|
+
case "motebit-concat-ed25519-hex-v1":
|
|
3185
|
+
case "eddsa-jcs-2022":
|
|
3186
|
+
return getPublicKeyAsync(privateKey);
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
function verifyP256EcdsaSha256(publicKeyCompressedHex, messageBytes, signatureDerBytes) {
|
|
3190
|
+
try {
|
|
3191
|
+
const digest = sha256(messageBytes);
|
|
3192
|
+
const pubKeyBytes = hexToBytes3(publicKeyCompressedHex);
|
|
3193
|
+
return p256.verify(signatureDerBytes, digest, pubKeyBytes, { prehash: false });
|
|
3194
|
+
} catch {
|
|
3195
|
+
return false;
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
function hexToBytes3(hex) {
|
|
3199
|
+
const clean = hex.startsWith("0x") || hex.startsWith("0X") ? hex.slice(2) : hex;
|
|
3200
|
+
if (clean.length % 2 !== 0) throw new Error("hex length must be even");
|
|
3201
|
+
const out = new Uint8Array(clean.length / 2);
|
|
3202
|
+
for (let i = 0; i < out.length; i++) {
|
|
3203
|
+
const byte = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
3204
|
+
if (Number.isNaN(byte)) throw new Error(`invalid hex at position ${i * 2}`);
|
|
3205
|
+
out[i] = byte;
|
|
3206
|
+
}
|
|
3207
|
+
return out;
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
// src/signing.ts
|
|
3211
|
+
if (!hashes.sha512) {
|
|
3212
|
+
hashes.sha512 = (msg) => sha512(msg);
|
|
3213
|
+
}
|
|
3214
|
+
var SIGNED_TOKEN_SUITE = "motebit-jwt-ed25519-v1";
|
|
3215
|
+
function canonicalJson(obj) {
|
|
3216
|
+
if (obj === null || obj === void 0) return JSON.stringify(obj);
|
|
3217
|
+
if (typeof obj !== "object") return JSON.stringify(obj);
|
|
3218
|
+
if (Array.isArray(obj)) {
|
|
3219
|
+
return "[" + obj.map((item) => canonicalJson(item)).join(",") + "]";
|
|
3220
|
+
}
|
|
3221
|
+
const sorted = Object.keys(obj).sort();
|
|
3222
|
+
const entries = [];
|
|
3223
|
+
for (const key of sorted) {
|
|
3224
|
+
const val = obj[key];
|
|
3225
|
+
if (val === void 0) continue;
|
|
3226
|
+
entries.push(JSON.stringify(key) + ":" + canonicalJson(val));
|
|
3227
|
+
}
|
|
3228
|
+
return "{" + entries.join(",") + "}";
|
|
3229
|
+
}
|
|
3230
|
+
function bytesToHex3(bytes) {
|
|
3231
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3232
|
+
}
|
|
3233
|
+
function hexToBytes4(hex) {
|
|
3234
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
3235
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
3236
|
+
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
3237
|
+
}
|
|
3238
|
+
return bytes;
|
|
3239
|
+
}
|
|
3240
|
+
function toBase64Url(data) {
|
|
3241
|
+
let binary = "";
|
|
3242
|
+
for (let i = 0; i < data.length; i++) {
|
|
3243
|
+
binary += String.fromCharCode(data[i]);
|
|
3244
|
+
}
|
|
3245
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3246
|
+
}
|
|
3247
|
+
function fromBase64Url(str) {
|
|
3248
|
+
const padded = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
3249
|
+
const binary = atob(padded);
|
|
3250
|
+
const bytes = new Uint8Array(binary.length);
|
|
3251
|
+
for (let i = 0; i < binary.length; i++) {
|
|
3252
|
+
bytes[i] = binary.charCodeAt(i);
|
|
3253
|
+
}
|
|
3254
|
+
return bytes;
|
|
3255
|
+
}
|
|
3256
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
3257
|
+
function base58btcEncode(bytes) {
|
|
3258
|
+
let zeros = 0;
|
|
3259
|
+
while (zeros < bytes.length && bytes[zeros] === 0) zeros++;
|
|
3260
|
+
let value = 0n;
|
|
3261
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
3262
|
+
value = value * 256n + BigInt(bytes[i]);
|
|
3263
|
+
}
|
|
3264
|
+
let result = "";
|
|
3265
|
+
while (value > 0n) {
|
|
3266
|
+
const remainder = Number(value % 58n);
|
|
3267
|
+
value = value / 58n;
|
|
3268
|
+
result = BASE58_ALPHABET[remainder] + result;
|
|
3269
|
+
}
|
|
3270
|
+
return BASE58_ALPHABET[0].repeat(zeros) + result;
|
|
3271
|
+
}
|
|
3272
|
+
function base58btcDecode(str) {
|
|
3273
|
+
let zeros = 0;
|
|
3274
|
+
while (zeros < str.length && str[zeros] === BASE58_ALPHABET[0]) zeros++;
|
|
3275
|
+
let value = 0n;
|
|
3276
|
+
for (let i = 0; i < str.length; i++) {
|
|
3277
|
+
const idx = BASE58_ALPHABET.indexOf(str[i]);
|
|
3278
|
+
if (idx === -1) throw new Error(`Invalid base58 character: ${str[i]}`);
|
|
3279
|
+
value = value * 58n + BigInt(idx);
|
|
3280
|
+
}
|
|
3281
|
+
const hex = [];
|
|
3282
|
+
while (value > 0n) {
|
|
3283
|
+
const byte = Number(value & 0xffn);
|
|
3284
|
+
hex.unshift(byte.toString(16).padStart(2, "0"));
|
|
3285
|
+
value >>= 8n;
|
|
3286
|
+
}
|
|
3287
|
+
const dataBytes = hex.length > 0 ? new Uint8Array(hex.map((h2) => parseInt(h2, 16))) : new Uint8Array(0);
|
|
3288
|
+
const result = new Uint8Array(zeros + dataBytes.length);
|
|
3289
|
+
result.set(dataBytes, zeros);
|
|
3290
|
+
return result;
|
|
3291
|
+
}
|
|
3292
|
+
function didKeyToPublicKey(did) {
|
|
3293
|
+
if (!did.startsWith("did:key:z")) {
|
|
3294
|
+
throw new Error("Invalid did:key URI: must start with did:key:z");
|
|
3295
|
+
}
|
|
3296
|
+
const encoded = did.slice("did:key:z".length);
|
|
3297
|
+
const decoded = base58btcDecode(encoded);
|
|
3298
|
+
if (decoded.length !== 34) {
|
|
3299
|
+
throw new Error(
|
|
3300
|
+
`Invalid did:key: expected 34 bytes (2 prefix + 32 key), got ${decoded.length}`
|
|
3301
|
+
);
|
|
3302
|
+
}
|
|
3303
|
+
if (decoded[0] !== 237 || decoded[1] !== 1) {
|
|
3304
|
+
throw new Error("Invalid did:key: multicodec prefix is not ed25519-pub (0xed01)");
|
|
3305
|
+
}
|
|
3306
|
+
return decoded.slice(2);
|
|
3307
|
+
}
|
|
3308
|
+
function publicKeyToDidKey(publicKey) {
|
|
3309
|
+
if (publicKey.length !== 32) {
|
|
3310
|
+
throw new Error("Ed25519 public key must be 32 bytes");
|
|
3311
|
+
}
|
|
3312
|
+
const prefixed = new Uint8Array(34);
|
|
3313
|
+
prefixed[0] = 237;
|
|
3314
|
+
prefixed[1] = 1;
|
|
3315
|
+
prefixed.set(publicKey, 2);
|
|
3316
|
+
return `did:key:z${base58btcEncode(prefixed)}`;
|
|
3317
|
+
}
|
|
3318
|
+
function hexPublicKeyToDidKey(hexPublicKey) {
|
|
3319
|
+
return publicKeyToDidKey(hexToBytes4(hexPublicKey));
|
|
3320
|
+
}
|
|
3321
|
+
async function hash(data) {
|
|
3322
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
3323
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
3324
|
+
return Array.from(hashArray).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3325
|
+
}
|
|
3326
|
+
async function canonicalSha256(obj) {
|
|
3327
|
+
return hash(new TextEncoder().encode(canonicalJson(obj)));
|
|
3328
|
+
}
|
|
3329
|
+
async function sha2563(data) {
|
|
3330
|
+
const buf = await crypto.subtle.digest("SHA-256", data);
|
|
3331
|
+
return new Uint8Array(buf);
|
|
3332
|
+
}
|
|
3333
|
+
async function generateKeypair() {
|
|
3334
|
+
return generateEd25519Keypair();
|
|
3335
|
+
}
|
|
3336
|
+
async function createSignedToken(payload, privateKey) {
|
|
3337
|
+
const withSuite = { ...payload, suite: SIGNED_TOKEN_SUITE };
|
|
3338
|
+
const payloadBytes = new TextEncoder().encode(JSON.stringify(withSuite));
|
|
3339
|
+
const payloadB64 = toBase64Url(payloadBytes);
|
|
3340
|
+
const signature = await signBySuite(SIGNED_TOKEN_SUITE, payloadBytes, privateKey);
|
|
3341
|
+
const sigB64 = toBase64Url(signature);
|
|
3342
|
+
return `${payloadB64}.${sigB64}`;
|
|
3343
|
+
}
|
|
3344
|
+
async function verifySignedToken(token, publicKey) {
|
|
3345
|
+
const dotIdx = token.indexOf(".");
|
|
3346
|
+
if (dotIdx === -1) return null;
|
|
3347
|
+
const payloadB64 = token.slice(0, dotIdx);
|
|
3348
|
+
const sigB64 = token.slice(dotIdx + 1);
|
|
3349
|
+
let payloadBytes;
|
|
3350
|
+
let signature;
|
|
3351
|
+
try {
|
|
3352
|
+
payloadBytes = fromBase64Url(payloadB64);
|
|
3353
|
+
signature = fromBase64Url(sigB64);
|
|
3354
|
+
} catch {
|
|
3355
|
+
return null;
|
|
3356
|
+
}
|
|
3357
|
+
let payload;
|
|
3358
|
+
try {
|
|
3359
|
+
payload = JSON.parse(new TextDecoder().decode(payloadBytes));
|
|
3360
|
+
} catch {
|
|
3361
|
+
return null;
|
|
3362
|
+
}
|
|
3363
|
+
if (payload.suite !== SIGNED_TOKEN_SUITE) return null;
|
|
3364
|
+
const valid = await verifyBySuite(payload.suite, payloadBytes, signature, publicKey);
|
|
3365
|
+
if (!valid) return null;
|
|
3366
|
+
if (payload.exp <= Date.now()) return null;
|
|
3367
|
+
if (!payload.jti) return null;
|
|
3368
|
+
if (!payload.aud) return null;
|
|
3369
|
+
return payload;
|
|
3370
|
+
}
|
|
3371
|
+
function parseScopeSet(scope) {
|
|
3372
|
+
if (scope === "*") return /* @__PURE__ */ new Set(["*"]);
|
|
3373
|
+
return new Set(
|
|
3374
|
+
scope.split(",").map((s) => s.trim()).filter((s) => s.length > 0)
|
|
3375
|
+
);
|
|
3376
|
+
}
|
|
3377
|
+
function isScopeNarrowed(parentScope, childScope) {
|
|
3378
|
+
const parent = parseScopeSet(parentScope);
|
|
3379
|
+
const child = parseScopeSet(childScope);
|
|
3380
|
+
if (parent.has("*")) return true;
|
|
3381
|
+
if (child.has("*")) return false;
|
|
3382
|
+
for (const cap of child) {
|
|
3383
|
+
if (!parent.has(cap)) return false;
|
|
3384
|
+
}
|
|
3385
|
+
return true;
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
// src/hardware-attestation.ts
|
|
3389
|
+
function verifyHardwareAttestationClaim(claim, expectedIdentityPublicKeyHex, verifiers, deviceCheckContext) {
|
|
3390
|
+
const platform = claim.platform;
|
|
3391
|
+
const errors = [];
|
|
3392
|
+
switch (platform) {
|
|
3393
|
+
case "secure_enclave":
|
|
3394
|
+
return verifySecureEnclaveClaim(claim, expectedIdentityPublicKeyHex);
|
|
3395
|
+
case "software":
|
|
3396
|
+
errors.push({
|
|
3397
|
+
message: "platform `software` is a no-hardware sentinel; no verification channel"
|
|
3398
|
+
});
|
|
3399
|
+
return { valid: false, platform: "software", errors };
|
|
3400
|
+
case "device_check":
|
|
3401
|
+
if (verifiers?.deviceCheck) {
|
|
3402
|
+
return dispatchInjected(
|
|
3403
|
+
platform,
|
|
3404
|
+
verifiers.deviceCheck(claim, expectedIdentityPublicKeyHex, deviceCheckContext)
|
|
3405
|
+
);
|
|
3406
|
+
}
|
|
3407
|
+
errors.push({
|
|
3408
|
+
message: `platform \`${platform}\` verifier not wired \u2014 pass { deviceCheck: deviceCheckVerifier(...) } from @motebit/crypto-appattest to enable`
|
|
3409
|
+
});
|
|
3410
|
+
return { valid: false, platform, errors };
|
|
3411
|
+
case "tpm":
|
|
3412
|
+
if (verifiers?.tpm) {
|
|
3413
|
+
return dispatchInjected(
|
|
3414
|
+
platform,
|
|
3415
|
+
verifiers.tpm(claim, expectedIdentityPublicKeyHex, deviceCheckContext)
|
|
3416
|
+
);
|
|
3417
|
+
}
|
|
3418
|
+
errors.push({
|
|
3419
|
+
message: `platform \`${platform}\` verifier not wired \u2014 pass { tpm: ... } via the verifiers parameter to enable`
|
|
3420
|
+
});
|
|
3421
|
+
return { valid: false, platform, errors };
|
|
3422
|
+
case "play_integrity":
|
|
3423
|
+
if (verifiers?.playIntegrity) {
|
|
3424
|
+
return dispatchInjected(
|
|
3425
|
+
platform,
|
|
3426
|
+
verifiers.playIntegrity(claim, expectedIdentityPublicKeyHex, deviceCheckContext)
|
|
3427
|
+
);
|
|
3428
|
+
}
|
|
3429
|
+
errors.push({
|
|
3430
|
+
message: `platform \`${platform}\` verifier not wired \u2014 pass { playIntegrity: ... } via the verifiers parameter to enable`
|
|
3431
|
+
});
|
|
3432
|
+
return { valid: false, platform, errors };
|
|
3433
|
+
case "webauthn":
|
|
3434
|
+
if (verifiers?.webauthn) {
|
|
3435
|
+
return dispatchInjected(
|
|
3436
|
+
platform,
|
|
3437
|
+
verifiers.webauthn(claim, expectedIdentityPublicKeyHex, deviceCheckContext)
|
|
3438
|
+
);
|
|
3439
|
+
}
|
|
3440
|
+
errors.push({
|
|
3441
|
+
message: `platform \`${platform}\` verifier not wired \u2014 pass { webauthn: webauthnVerifier(...) } from @motebit/crypto-webauthn to enable`
|
|
3442
|
+
});
|
|
3443
|
+
return { valid: false, platform, errors };
|
|
3444
|
+
default:
|
|
3445
|
+
errors.push({
|
|
3446
|
+
message: `unknown platform \`${claim.platform}\` \u2014 not in the declared enum`
|
|
3447
|
+
});
|
|
3448
|
+
return { valid: false, platform: null, errors };
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
async function dispatchInjected(platform, result) {
|
|
3452
|
+
const awaited = await Promise.resolve(result);
|
|
3453
|
+
return {
|
|
3454
|
+
valid: awaited.valid,
|
|
3455
|
+
platform,
|
|
3456
|
+
errors: awaited.errors ?? []
|
|
3457
|
+
};
|
|
3458
|
+
}
|
|
3459
|
+
function verifySecureEnclaveClaim(claim, expectedIdentityPublicKeyHex) {
|
|
3460
|
+
const errors = [];
|
|
3461
|
+
const platform = "secure_enclave";
|
|
3462
|
+
if (claim.key_exported === true) {
|
|
3463
|
+
}
|
|
3464
|
+
if (!claim.attestation_receipt) {
|
|
3465
|
+
errors.push({
|
|
3466
|
+
message: "secure_enclave claim missing `attestation_receipt`"
|
|
3467
|
+
});
|
|
3468
|
+
return { valid: false, platform, errors };
|
|
3469
|
+
}
|
|
3470
|
+
const parts = claim.attestation_receipt.split(".");
|
|
3471
|
+
if (parts.length !== 2) {
|
|
3472
|
+
errors.push({
|
|
3473
|
+
message: `attestation_receipt must be 2 base64url parts separated by '.'; got ${parts.length}`
|
|
3474
|
+
});
|
|
3475
|
+
return { valid: false, platform, errors };
|
|
3476
|
+
}
|
|
3477
|
+
const [bodyB64, sigB64] = parts;
|
|
3478
|
+
let bodyBytes;
|
|
3479
|
+
let sigBytes;
|
|
3480
|
+
try {
|
|
3481
|
+
bodyBytes = fromBase64Url(bodyB64);
|
|
3482
|
+
sigBytes = fromBase64Url(sigB64);
|
|
3483
|
+
} catch (err2) {
|
|
3484
|
+
errors.push({
|
|
3485
|
+
message: `base64url decode failed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
3486
|
+
});
|
|
3487
|
+
return { valid: false, platform, errors };
|
|
3488
|
+
}
|
|
3489
|
+
let bodyJson;
|
|
3490
|
+
try {
|
|
3491
|
+
bodyJson = JSON.parse(new TextDecoder().decode(bodyBytes));
|
|
3492
|
+
} catch (err2) {
|
|
3493
|
+
errors.push({
|
|
3494
|
+
message: `body JSON parse failed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
3495
|
+
});
|
|
3496
|
+
return { valid: false, platform, errors };
|
|
3497
|
+
}
|
|
3498
|
+
const bodyCheck = parseSecureEnclaveBody(bodyJson);
|
|
3499
|
+
if (bodyCheck.kind === "error") {
|
|
3500
|
+
errors.push({ message: bodyCheck.reason });
|
|
3501
|
+
return { valid: false, platform, errors };
|
|
3502
|
+
}
|
|
3503
|
+
const body = bodyCheck.body;
|
|
3504
|
+
if (body.version !== "1") {
|
|
3505
|
+
errors.push({
|
|
3506
|
+
message: `unsupported body version '${body.version}' (expected '1')`
|
|
3507
|
+
});
|
|
3508
|
+
return { valid: false, platform, errors };
|
|
3509
|
+
}
|
|
3510
|
+
if (body.algorithm !== "ecdsa-p256-sha256") {
|
|
3511
|
+
errors.push({
|
|
3512
|
+
message: `unsupported body algorithm '${body.algorithm}' (expected 'ecdsa-p256-sha256')`
|
|
3513
|
+
});
|
|
3514
|
+
return { valid: false, platform, errors };
|
|
3515
|
+
}
|
|
3516
|
+
let sigValid;
|
|
3517
|
+
try {
|
|
3518
|
+
sigValid = verifyP256EcdsaSha256(body.se_public_key, bodyBytes, sigBytes);
|
|
3519
|
+
} catch (err2) {
|
|
3520
|
+
errors.push({
|
|
3521
|
+
message: `p-256 verification crashed: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
3522
|
+
});
|
|
3523
|
+
return { valid: false, platform, errors };
|
|
3524
|
+
}
|
|
3525
|
+
if (!sigValid) {
|
|
3526
|
+
errors.push({
|
|
3527
|
+
message: "p-256 signature does not verify against body + se_public_key"
|
|
3528
|
+
});
|
|
3529
|
+
return { valid: false, platform, errors };
|
|
3530
|
+
}
|
|
3531
|
+
if (body.identity_public_key.toLowerCase() !== expectedIdentityPublicKeyHex.toLowerCase()) {
|
|
3532
|
+
errors.push({
|
|
3533
|
+
message: `identity_public_key mismatch: body names ${body.identity_public_key.slice(0, 16)}\u2026, expected ${expectedIdentityPublicKeyHex.slice(0, 16)}\u2026`
|
|
3534
|
+
});
|
|
3535
|
+
return { valid: false, platform, errors };
|
|
3536
|
+
}
|
|
3537
|
+
return {
|
|
3538
|
+
valid: true,
|
|
3539
|
+
platform,
|
|
3540
|
+
se_public_key: body.se_public_key,
|
|
3541
|
+
attested_at: body.attested_at,
|
|
3542
|
+
errors: []
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
function parseSecureEnclaveBody(raw) {
|
|
3546
|
+
if (raw === null || typeof raw !== "object") {
|
|
3547
|
+
return { kind: "error", reason: "body is not a JSON object" };
|
|
3548
|
+
}
|
|
3549
|
+
const r = raw;
|
|
3550
|
+
const fields = [
|
|
3551
|
+
"version",
|
|
3552
|
+
"algorithm",
|
|
3553
|
+
"motebit_id",
|
|
3554
|
+
"device_id",
|
|
3555
|
+
"identity_public_key",
|
|
3556
|
+
"se_public_key",
|
|
3557
|
+
"attested_at"
|
|
3558
|
+
];
|
|
3559
|
+
for (const f of fields) {
|
|
3560
|
+
if (!(f in r)) {
|
|
3561
|
+
return { kind: "error", reason: `body missing required field '${f}'` };
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
if (typeof r.version !== "string" || typeof r.algorithm !== "string" || typeof r.motebit_id !== "string" || typeof r.device_id !== "string" || typeof r.identity_public_key !== "string" || typeof r.se_public_key !== "string" || typeof r.attested_at !== "number") {
|
|
3565
|
+
return { kind: "error", reason: "body field types invalid" };
|
|
3566
|
+
}
|
|
3567
|
+
return {
|
|
3568
|
+
kind: "ok",
|
|
3569
|
+
body: {
|
|
3570
|
+
version: r.version,
|
|
3571
|
+
algorithm: r.algorithm,
|
|
3572
|
+
motebit_id: r.motebit_id,
|
|
3573
|
+
device_id: r.device_id,
|
|
3574
|
+
identity_public_key: r.identity_public_key,
|
|
3575
|
+
se_public_key: r.se_public_key,
|
|
3576
|
+
attested_at: r.attested_at
|
|
3577
|
+
}
|
|
3578
|
+
};
|
|
3579
|
+
}
|
|
3580
|
+
function encodeSecureEnclaveReceiptForTest(bodyBytes, sigBytes) {
|
|
3581
|
+
return `${toBase64Url2(bodyBytes)}.${toBase64Url2(sigBytes)}`;
|
|
3582
|
+
}
|
|
3583
|
+
function canonicalSecureEnclaveBodyForTest(body) {
|
|
3584
|
+
const full = {
|
|
3585
|
+
version: "1",
|
|
3586
|
+
algorithm: "ecdsa-p256-sha256",
|
|
3587
|
+
...body
|
|
3588
|
+
};
|
|
3589
|
+
return new TextEncoder().encode(canonicalJson(full));
|
|
3590
|
+
}
|
|
3591
|
+
function toBase64Url2(bytes) {
|
|
3592
|
+
let binary = "";
|
|
3593
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
3594
|
+
binary += String.fromCharCode(bytes[i]);
|
|
1087
3595
|
}
|
|
1088
|
-
return
|
|
3596
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1089
3597
|
}
|
|
1090
3598
|
|
|
1091
3599
|
// src/artifacts.ts
|
|
3600
|
+
function isReceiptDebugEnabled() {
|
|
3601
|
+
const g = globalThis;
|
|
3602
|
+
if (g.__motebit_debug_receipt_bytes === true) return true;
|
|
3603
|
+
const flag = g.process?.env?.DEBUG_RECEIPT_BYTES;
|
|
3604
|
+
return flag === "1" || flag === "true";
|
|
3605
|
+
}
|
|
3606
|
+
var EXECUTION_RECEIPT_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
1092
3607
|
async function signExecutionReceipt(receipt, privateKey, publicKey) {
|
|
1093
|
-
const
|
|
3608
|
+
const withKey = publicKey ? { ...receipt, public_key: bytesToHex3(publicKey) } : receipt;
|
|
3609
|
+
const body = { ...withKey, suite: EXECUTION_RECEIPT_SUITE };
|
|
1094
3610
|
const canonical = canonicalJson(body);
|
|
1095
3611
|
const message = new TextEncoder().encode(canonical);
|
|
1096
|
-
const sig = await
|
|
1097
|
-
|
|
3612
|
+
const sig = await signBySuite(EXECUTION_RECEIPT_SUITE, message, privateKey);
|
|
3613
|
+
const signed = { ...body, signature: toBase64Url(sig) };
|
|
3614
|
+
if (isReceiptDebugEnabled()) {
|
|
3615
|
+
const sha = await canonicalSha256(body);
|
|
3616
|
+
console.debug(
|
|
3617
|
+
`[motebit/crypto] signExecutionReceipt canonical_sha256=${sha} chain=${Array.isArray(body.delegation_receipts) ? body.delegation_receipts.length : 0} bytes=${canonical.length}`
|
|
3618
|
+
);
|
|
3619
|
+
}
|
|
3620
|
+
return Object.freeze(signed);
|
|
1098
3621
|
}
|
|
1099
3622
|
async function verifyExecutionReceipt(receipt, publicKey) {
|
|
3623
|
+
if (receipt.suite !== EXECUTION_RECEIPT_SUITE) {
|
|
3624
|
+
if (isReceiptDebugEnabled()) {
|
|
3625
|
+
console.debug(
|
|
3626
|
+
`[motebit/crypto] verifyExecutionReceipt EARLY_RETURN suite_mismatch actual=${JSON.stringify(receipt.suite)} expected=${JSON.stringify(EXECUTION_RECEIPT_SUITE)}`
|
|
3627
|
+
);
|
|
3628
|
+
}
|
|
3629
|
+
return false;
|
|
3630
|
+
}
|
|
1100
3631
|
const { signature, ...body } = receipt;
|
|
1101
3632
|
const canonical = canonicalJson(body);
|
|
1102
3633
|
const message = new TextEncoder().encode(canonical);
|
|
3634
|
+
let valid = false;
|
|
1103
3635
|
try {
|
|
1104
3636
|
const sig = fromBase64Url(signature);
|
|
1105
|
-
|
|
3637
|
+
valid = await verifyBySuite(receipt.suite, message, sig, publicKey);
|
|
3638
|
+
} catch {
|
|
3639
|
+
valid = false;
|
|
3640
|
+
}
|
|
3641
|
+
if (isReceiptDebugEnabled()) {
|
|
3642
|
+
const sha = await canonicalSha256(body);
|
|
3643
|
+
console.debug(
|
|
3644
|
+
`[motebit/crypto] verifyExecutionReceipt canonical_sha256=${sha} valid=${valid} bytes=${canonical.length}`
|
|
3645
|
+
);
|
|
3646
|
+
}
|
|
3647
|
+
return valid;
|
|
3648
|
+
}
|
|
3649
|
+
async function verifyExecutionReceiptDetailed(receipt, publicKey) {
|
|
3650
|
+
if (receipt.suite !== EXECUTION_RECEIPT_SUITE) {
|
|
3651
|
+
const { signature: _drop, ...bodyForHash } = receipt;
|
|
3652
|
+
return {
|
|
3653
|
+
valid: false,
|
|
3654
|
+
canonical_sha256: await canonicalSha256(bodyForHash),
|
|
3655
|
+
canonical_preview: canonicalJson(bodyForHash).slice(0, 256),
|
|
3656
|
+
reason: "wrong_suite"
|
|
3657
|
+
};
|
|
3658
|
+
}
|
|
3659
|
+
const { signature, ...body } = receipt;
|
|
3660
|
+
const canonical = canonicalJson(body);
|
|
3661
|
+
const message = new TextEncoder().encode(canonical);
|
|
3662
|
+
let sigBytes;
|
|
3663
|
+
try {
|
|
3664
|
+
sigBytes = fromBase64Url(signature);
|
|
1106
3665
|
} catch {
|
|
3666
|
+
return {
|
|
3667
|
+
valid: false,
|
|
3668
|
+
canonical_sha256: await hash(message),
|
|
3669
|
+
canonical_preview: canonical.slice(0, 256),
|
|
3670
|
+
reason: "bad_base64"
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
const valid = await verifyBySuite(receipt.suite, message, sigBytes, publicKey);
|
|
3674
|
+
return {
|
|
3675
|
+
valid,
|
|
3676
|
+
canonical_sha256: await hash(message),
|
|
3677
|
+
canonical_preview: canonical.slice(0, 256),
|
|
3678
|
+
reason: valid ? "ok" : "ed25519_mismatch"
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
var TOOL_INVOCATION_RECEIPT_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3682
|
+
async function hashToolPayload(value) {
|
|
3683
|
+
return canonicalSha256(value);
|
|
3684
|
+
}
|
|
3685
|
+
async function signToolInvocationReceipt(receipt, privateKey, publicKey) {
|
|
3686
|
+
const withKey = publicKey ? { ...receipt, public_key: bytesToHex3(publicKey) } : receipt;
|
|
3687
|
+
const body = { ...withKey, suite: TOOL_INVOCATION_RECEIPT_SUITE };
|
|
3688
|
+
const canonical = canonicalJson(body);
|
|
3689
|
+
const message = new TextEncoder().encode(canonical);
|
|
3690
|
+
const sig = await signBySuite(TOOL_INVOCATION_RECEIPT_SUITE, message, privateKey);
|
|
3691
|
+
const signed = { ...body, signature: toBase64Url(sig) };
|
|
3692
|
+
if (isReceiptDebugEnabled()) {
|
|
3693
|
+
const sha = await canonicalSha256(body);
|
|
3694
|
+
console.debug(
|
|
3695
|
+
`[motebit/crypto] signToolInvocationReceipt canonical_sha256=${sha} tool=${body.tool_name} bytes=${canonical.length}`
|
|
3696
|
+
);
|
|
3697
|
+
}
|
|
3698
|
+
return Object.freeze(signed);
|
|
3699
|
+
}
|
|
3700
|
+
async function verifyToolInvocationReceipt(receipt, publicKey) {
|
|
3701
|
+
if (receipt.suite !== TOOL_INVOCATION_RECEIPT_SUITE) {
|
|
3702
|
+
if (isReceiptDebugEnabled()) {
|
|
3703
|
+
console.debug(
|
|
3704
|
+
`[motebit/crypto] verifyToolInvocationReceipt EARLY_RETURN suite_mismatch actual=${JSON.stringify(receipt.suite)} expected=${JSON.stringify(TOOL_INVOCATION_RECEIPT_SUITE)}`
|
|
3705
|
+
);
|
|
3706
|
+
}
|
|
1107
3707
|
return false;
|
|
1108
3708
|
}
|
|
3709
|
+
const { signature, ...body } = receipt;
|
|
3710
|
+
const canonical = canonicalJson(body);
|
|
3711
|
+
const message = new TextEncoder().encode(canonical);
|
|
3712
|
+
let valid = false;
|
|
3713
|
+
try {
|
|
3714
|
+
const sig = fromBase64Url(signature);
|
|
3715
|
+
valid = await verifyBySuite(receipt.suite, message, sig, publicKey);
|
|
3716
|
+
} catch {
|
|
3717
|
+
valid = false;
|
|
3718
|
+
}
|
|
3719
|
+
if (isReceiptDebugEnabled()) {
|
|
3720
|
+
const sha = await canonicalSha256(body);
|
|
3721
|
+
console.debug(
|
|
3722
|
+
`[motebit/crypto] verifyToolInvocationReceipt canonical_sha256=${sha} valid=${valid} bytes=${canonical.length}`
|
|
3723
|
+
);
|
|
3724
|
+
}
|
|
3725
|
+
return valid;
|
|
1109
3726
|
}
|
|
1110
3727
|
async function signSovereignPaymentReceipt(input, privateKey, publicKey) {
|
|
1111
3728
|
const receipt = {
|
|
@@ -1121,6 +3738,7 @@ async function signSovereignPaymentReceipt(input, privateKey, publicKey) {
|
|
|
1121
3738
|
prompt_hash: input.prompt_hash,
|
|
1122
3739
|
result_hash: input.result_hash
|
|
1123
3740
|
// relay_task_id intentionally omitted — sovereign rail, no relay binding
|
|
3741
|
+
// suite is stamped by signExecutionReceipt
|
|
1124
3742
|
};
|
|
1125
3743
|
return signExecutionReceipt(receipt, privateKey, publicKey);
|
|
1126
3744
|
}
|
|
@@ -1128,7 +3746,7 @@ async function verifyReceiptChain(receipt, knownKeys) {
|
|
|
1128
3746
|
const { task_id, motebit_id } = receipt;
|
|
1129
3747
|
let publicKey = knownKeys.get(motebit_id);
|
|
1130
3748
|
if (!publicKey && receipt.public_key) {
|
|
1131
|
-
publicKey =
|
|
3749
|
+
publicKey = hexToBytes4(receipt.public_key);
|
|
1132
3750
|
}
|
|
1133
3751
|
if (!publicKey) {
|
|
1134
3752
|
const delegations2 = await verifyDelegations(receipt, knownKeys);
|
|
@@ -1177,13 +3795,16 @@ async function verifyReceiptSequence(chain) {
|
|
|
1177
3795
|
}
|
|
1178
3796
|
return { valid: true };
|
|
1179
3797
|
}
|
|
3798
|
+
var DELEGATION_TOKEN_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
1180
3799
|
async function signDelegation(delegation, delegatorPrivateKey) {
|
|
1181
|
-
const
|
|
3800
|
+
const body = { ...delegation, suite: DELEGATION_TOKEN_SUITE };
|
|
3801
|
+
const canonical = canonicalJson(body);
|
|
1182
3802
|
const message = new TextEncoder().encode(canonical);
|
|
1183
|
-
const sig = await
|
|
1184
|
-
return { ...
|
|
3803
|
+
const sig = await signBySuite(DELEGATION_TOKEN_SUITE, message, delegatorPrivateKey);
|
|
3804
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
1185
3805
|
}
|
|
1186
3806
|
async function verifyDelegation(delegation, options) {
|
|
3807
|
+
if (delegation.suite !== DELEGATION_TOKEN_SUITE) return false;
|
|
1187
3808
|
const checkExpiry = options?.checkExpiry ?? true;
|
|
1188
3809
|
if (checkExpiry) {
|
|
1189
3810
|
const now = options?.now ?? Date.now();
|
|
@@ -1193,9 +3814,9 @@ async function verifyDelegation(delegation, options) {
|
|
|
1193
3814
|
const canonical = canonicalJson(body);
|
|
1194
3815
|
const message = new TextEncoder().encode(canonical);
|
|
1195
3816
|
try {
|
|
1196
|
-
const pubKey =
|
|
3817
|
+
const pubKey = hexToBytes4(delegation.delegator_public_key);
|
|
1197
3818
|
const sig = fromBase64Url(signature);
|
|
1198
|
-
return await
|
|
3819
|
+
return await verifyBySuite(delegation.suite, message, sig, pubKey);
|
|
1199
3820
|
} catch {
|
|
1200
3821
|
return false;
|
|
1201
3822
|
}
|
|
@@ -1232,11 +3853,186 @@ async function verifyDelegationChain(chain) {
|
|
|
1232
3853
|
}
|
|
1233
3854
|
return { valid: true };
|
|
1234
3855
|
}
|
|
3856
|
+
var ADJUDICATOR_VOTE_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3857
|
+
var DISPUTE_RESOLUTION_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3858
|
+
var DISPUTE_REQUEST_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3859
|
+
var DISPUTE_EVIDENCE_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3860
|
+
var DISPUTE_APPEAL_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3861
|
+
async function signAdjudicatorVote(vote, peerPrivateKey) {
|
|
3862
|
+
const body = { ...vote, suite: ADJUDICATOR_VOTE_SUITE };
|
|
3863
|
+
const canonical = canonicalJson(body);
|
|
3864
|
+
const message = new TextEncoder().encode(canonical);
|
|
3865
|
+
const sig = await signBySuite(ADJUDICATOR_VOTE_SUITE, message, peerPrivateKey);
|
|
3866
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
3867
|
+
}
|
|
3868
|
+
async function verifyAdjudicatorVote(vote, peerPublicKey) {
|
|
3869
|
+
if (vote.suite !== ADJUDICATOR_VOTE_SUITE) return false;
|
|
3870
|
+
const { signature, ...body } = vote;
|
|
3871
|
+
const canonical = canonicalJson(body);
|
|
3872
|
+
const message = new TextEncoder().encode(canonical);
|
|
3873
|
+
try {
|
|
3874
|
+
const sig = fromBase64Url(signature);
|
|
3875
|
+
return await verifyBySuite(vote.suite, message, sig, peerPublicKey);
|
|
3876
|
+
} catch {
|
|
3877
|
+
return false;
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
async function signDisputeResolution(resolution, adjudicatorPrivateKey) {
|
|
3881
|
+
const body = { ...resolution, suite: DISPUTE_RESOLUTION_SUITE };
|
|
3882
|
+
const canonical = canonicalJson(body);
|
|
3883
|
+
const message = new TextEncoder().encode(canonical);
|
|
3884
|
+
const sig = await signBySuite(DISPUTE_RESOLUTION_SUITE, message, adjudicatorPrivateKey);
|
|
3885
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
3886
|
+
}
|
|
3887
|
+
async function verifyDisputeResolution(resolution, adjudicatorPublicKey, peerKeys) {
|
|
3888
|
+
if (resolution.suite !== DISPUTE_RESOLUTION_SUITE) return false;
|
|
3889
|
+
const { signature, ...body } = resolution;
|
|
3890
|
+
const canonical = canonicalJson(body);
|
|
3891
|
+
const message = new TextEncoder().encode(canonical);
|
|
3892
|
+
try {
|
|
3893
|
+
const sig = fromBase64Url(signature);
|
|
3894
|
+
const outerValid = await verifyBySuite(resolution.suite, message, sig, adjudicatorPublicKey);
|
|
3895
|
+
if (!outerValid) return false;
|
|
3896
|
+
} catch {
|
|
3897
|
+
return false;
|
|
3898
|
+
}
|
|
3899
|
+
if (resolution.adjudicator_votes.length > 0) {
|
|
3900
|
+
if (!peerKeys) return false;
|
|
3901
|
+
for (const vote of resolution.adjudicator_votes) {
|
|
3902
|
+
if (vote.dispute_id !== resolution.dispute_id) return false;
|
|
3903
|
+
const peerKey = peerKeys.get(vote.peer_id);
|
|
3904
|
+
if (!peerKey) return false;
|
|
3905
|
+
const voteValid = await verifyAdjudicatorVote(vote, peerKey);
|
|
3906
|
+
if (!voteValid) return false;
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
return true;
|
|
3910
|
+
}
|
|
3911
|
+
async function signDisputeRequest(request, filerPrivateKey) {
|
|
3912
|
+
const body = { ...request, suite: DISPUTE_REQUEST_SUITE };
|
|
3913
|
+
const canonical = canonicalJson(body);
|
|
3914
|
+
const message = new TextEncoder().encode(canonical);
|
|
3915
|
+
const sig = await signBySuite(DISPUTE_REQUEST_SUITE, message, filerPrivateKey);
|
|
3916
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
3917
|
+
}
|
|
3918
|
+
async function verifyDisputeRequest(request, filerPublicKey) {
|
|
3919
|
+
if (request.suite !== DISPUTE_REQUEST_SUITE) return false;
|
|
3920
|
+
const { signature, ...body } = request;
|
|
3921
|
+
const canonical = canonicalJson(body);
|
|
3922
|
+
const message = new TextEncoder().encode(canonical);
|
|
3923
|
+
try {
|
|
3924
|
+
const sig = fromBase64Url(signature);
|
|
3925
|
+
return await verifyBySuite(request.suite, message, sig, filerPublicKey);
|
|
3926
|
+
} catch {
|
|
3927
|
+
return false;
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
async function signDisputeEvidence(evidence, submitterPrivateKey) {
|
|
3931
|
+
const body = { ...evidence, suite: DISPUTE_EVIDENCE_SUITE };
|
|
3932
|
+
const canonical = canonicalJson(body);
|
|
3933
|
+
const message = new TextEncoder().encode(canonical);
|
|
3934
|
+
const sig = await signBySuite(DISPUTE_EVIDENCE_SUITE, message, submitterPrivateKey);
|
|
3935
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
3936
|
+
}
|
|
3937
|
+
async function verifyDisputeEvidence(evidence, submitterPublicKey) {
|
|
3938
|
+
if (evidence.suite !== DISPUTE_EVIDENCE_SUITE) return false;
|
|
3939
|
+
const { signature, ...body } = evidence;
|
|
3940
|
+
const canonical = canonicalJson(body);
|
|
3941
|
+
const message = new TextEncoder().encode(canonical);
|
|
3942
|
+
try {
|
|
3943
|
+
const sig = fromBase64Url(signature);
|
|
3944
|
+
return await verifyBySuite(evidence.suite, message, sig, submitterPublicKey);
|
|
3945
|
+
} catch {
|
|
3946
|
+
return false;
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
async function signDisputeAppeal(appeal, appealerPrivateKey) {
|
|
3950
|
+
const body = { ...appeal, suite: DISPUTE_APPEAL_SUITE };
|
|
3951
|
+
const canonical = canonicalJson(body);
|
|
3952
|
+
const message = new TextEncoder().encode(canonical);
|
|
3953
|
+
const sig = await signBySuite(DISPUTE_APPEAL_SUITE, message, appealerPrivateKey);
|
|
3954
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
3955
|
+
}
|
|
3956
|
+
async function verifyDisputeAppeal(appeal, appealerPublicKey) {
|
|
3957
|
+
if (appeal.suite !== DISPUTE_APPEAL_SUITE) return false;
|
|
3958
|
+
const { signature, ...body } = appeal;
|
|
3959
|
+
const canonical = canonicalJson(body);
|
|
3960
|
+
const message = new TextEncoder().encode(canonical);
|
|
3961
|
+
try {
|
|
3962
|
+
const sig = fromBase64Url(signature);
|
|
3963
|
+
return await verifyBySuite(appeal.suite, message, sig, appealerPublicKey);
|
|
3964
|
+
} catch {
|
|
3965
|
+
return false;
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
var CONSOLIDATION_RECEIPT_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3969
|
+
async function signConsolidationReceipt(receipt, privateKey, publicKey) {
|
|
3970
|
+
const withKey = publicKey ? { ...receipt, public_key: bytesToHex3(publicKey) } : receipt;
|
|
3971
|
+
const body = { ...withKey, suite: CONSOLIDATION_RECEIPT_SUITE };
|
|
3972
|
+
const canonical = canonicalJson(body);
|
|
3973
|
+
const message = new TextEncoder().encode(canonical);
|
|
3974
|
+
const sig = await signBySuite(CONSOLIDATION_RECEIPT_SUITE, message, privateKey);
|
|
3975
|
+
return Object.freeze({ ...body, signature: toBase64Url(sig) });
|
|
3976
|
+
}
|
|
3977
|
+
async function verifyConsolidationReceipt(receipt, publicKey) {
|
|
3978
|
+
if (receipt.suite !== CONSOLIDATION_RECEIPT_SUITE) return false;
|
|
3979
|
+
const { signature, ...body } = receipt;
|
|
3980
|
+
const canonical = canonicalJson(body);
|
|
3981
|
+
const message = new TextEncoder().encode(canonical);
|
|
3982
|
+
try {
|
|
3983
|
+
const sig = fromBase64Url(signature);
|
|
3984
|
+
return await verifyBySuite(receipt.suite, message, sig, publicKey);
|
|
3985
|
+
} catch {
|
|
3986
|
+
return false;
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
var BALANCE_WAIVER_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
3990
|
+
async function signBalanceWaiver(waiver, agentPrivateKey) {
|
|
3991
|
+
const body = { ...waiver, suite: BALANCE_WAIVER_SUITE };
|
|
3992
|
+
const canonical = canonicalJson(body);
|
|
3993
|
+
const message = new TextEncoder().encode(canonical);
|
|
3994
|
+
const sig = await signBySuite(BALANCE_WAIVER_SUITE, message, agentPrivateKey);
|
|
3995
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
3996
|
+
}
|
|
3997
|
+
async function verifyBalanceWaiver(waiver, agentPublicKey) {
|
|
3998
|
+
if (waiver.suite !== BALANCE_WAIVER_SUITE) return false;
|
|
3999
|
+
const { signature, ...body } = waiver;
|
|
4000
|
+
const canonical = canonicalJson(body);
|
|
4001
|
+
const message = new TextEncoder().encode(canonical);
|
|
4002
|
+
try {
|
|
4003
|
+
const sig = fromBase64Url(signature);
|
|
4004
|
+
return await verifyBySuite(waiver.suite, message, sig, agentPublicKey);
|
|
4005
|
+
} catch {
|
|
4006
|
+
return false;
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
var SETTLEMENT_RECORD_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
4010
|
+
async function signSettlement(settlement, issuerPrivateKey) {
|
|
4011
|
+
const body = { ...settlement, suite: SETTLEMENT_RECORD_SUITE };
|
|
4012
|
+
const canonical = canonicalJson(body);
|
|
4013
|
+
const message = new TextEncoder().encode(canonical);
|
|
4014
|
+
const sig = await signBySuite(SETTLEMENT_RECORD_SUITE, message, issuerPrivateKey);
|
|
4015
|
+
return { ...body, signature: toBase64Url(sig) };
|
|
4016
|
+
}
|
|
4017
|
+
async function verifySettlement(settlement, issuerPublicKey) {
|
|
4018
|
+
if (settlement.suite !== SETTLEMENT_RECORD_SUITE) return false;
|
|
4019
|
+
const { signature, ...body } = settlement;
|
|
4020
|
+
const canonical = canonicalJson(body);
|
|
4021
|
+
const message = new TextEncoder().encode(canonical);
|
|
4022
|
+
try {
|
|
4023
|
+
const sig = fromBase64Url(signature);
|
|
4024
|
+
return await verifyBySuite(settlement.suite, message, sig, issuerPublicKey);
|
|
4025
|
+
} catch {
|
|
4026
|
+
return false;
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
var KEY_SUCCESSION_SUITE = "motebit-jcs-ed25519-hex-v1";
|
|
1235
4030
|
function keySuccessionPayload(oldPublicKeyHex, newPublicKeyHex, timestamp, reason, recovery) {
|
|
1236
4031
|
const obj = {
|
|
1237
4032
|
old_public_key: oldPublicKeyHex,
|
|
1238
4033
|
new_public_key: newPublicKeyHex,
|
|
1239
|
-
timestamp
|
|
4034
|
+
timestamp,
|
|
4035
|
+
suite: KEY_SUCCESSION_SUITE
|
|
1240
4036
|
};
|
|
1241
4037
|
if (reason !== void 0) {
|
|
1242
4038
|
obj.reason = reason;
|
|
@@ -1248,25 +4044,26 @@ function keySuccessionPayload(oldPublicKeyHex, newPublicKeyHex, timestamp, reaso
|
|
|
1248
4044
|
}
|
|
1249
4045
|
async function signKeySuccession(oldPrivateKey, newPrivateKey, newPublicKey, oldPublicKey, reason) {
|
|
1250
4046
|
const timestamp = Date.now();
|
|
1251
|
-
const oldPublicKeyHex =
|
|
1252
|
-
const newPublicKeyHex =
|
|
4047
|
+
const oldPublicKeyHex = bytesToHex3(oldPublicKey);
|
|
4048
|
+
const newPublicKeyHex = bytesToHex3(newPublicKey);
|
|
1253
4049
|
const payload = keySuccessionPayload(oldPublicKeyHex, newPublicKeyHex, timestamp, reason);
|
|
1254
4050
|
const message = new TextEncoder().encode(payload);
|
|
1255
|
-
const oldSig = await
|
|
1256
|
-
const newSig = await
|
|
4051
|
+
const oldSig = await signBySuite(KEY_SUCCESSION_SUITE, message, oldPrivateKey);
|
|
4052
|
+
const newSig = await signBySuite(KEY_SUCCESSION_SUITE, message, newPrivateKey);
|
|
1257
4053
|
return {
|
|
1258
4054
|
old_public_key: oldPublicKeyHex,
|
|
1259
4055
|
new_public_key: newPublicKeyHex,
|
|
1260
4056
|
timestamp,
|
|
1261
4057
|
...reason !== void 0 ? { reason } : {},
|
|
1262
|
-
|
|
1263
|
-
|
|
4058
|
+
suite: KEY_SUCCESSION_SUITE,
|
|
4059
|
+
old_key_signature: bytesToHex3(oldSig),
|
|
4060
|
+
new_key_signature: bytesToHex3(newSig)
|
|
1264
4061
|
};
|
|
1265
4062
|
}
|
|
1266
4063
|
async function signGuardianRecoverySuccession(guardianPrivateKey, newPrivateKey, oldPublicKey, newPublicKey, reason) {
|
|
1267
4064
|
const timestamp = Date.now();
|
|
1268
|
-
const oldPublicKeyHex =
|
|
1269
|
-
const newPublicKeyHex =
|
|
4065
|
+
const oldPublicKeyHex = bytesToHex3(oldPublicKey);
|
|
4066
|
+
const newPublicKeyHex = bytesToHex3(newPublicKey);
|
|
1270
4067
|
const effectiveReason = reason ?? "guardian_recovery";
|
|
1271
4068
|
const payload = keySuccessionPayload(
|
|
1272
4069
|
oldPublicKeyHex,
|
|
@@ -1276,19 +4073,21 @@ async function signGuardianRecoverySuccession(guardianPrivateKey, newPrivateKey,
|
|
|
1276
4073
|
true
|
|
1277
4074
|
);
|
|
1278
4075
|
const message = new TextEncoder().encode(payload);
|
|
1279
|
-
const guardianSig = await
|
|
1280
|
-
const newSig = await
|
|
4076
|
+
const guardianSig = await signBySuite(KEY_SUCCESSION_SUITE, message, guardianPrivateKey);
|
|
4077
|
+
const newSig = await signBySuite(KEY_SUCCESSION_SUITE, message, newPrivateKey);
|
|
1281
4078
|
return {
|
|
1282
4079
|
old_public_key: oldPublicKeyHex,
|
|
1283
4080
|
new_public_key: newPublicKeyHex,
|
|
1284
4081
|
timestamp,
|
|
1285
4082
|
reason: effectiveReason,
|
|
1286
|
-
|
|
4083
|
+
suite: KEY_SUCCESSION_SUITE,
|
|
4084
|
+
new_key_signature: bytesToHex3(newSig),
|
|
1287
4085
|
recovery: true,
|
|
1288
|
-
guardian_signature:
|
|
4086
|
+
guardian_signature: bytesToHex3(guardianSig)
|
|
1289
4087
|
};
|
|
1290
4088
|
}
|
|
1291
4089
|
async function verifyKeySuccession(record, guardianPublicKeyHex) {
|
|
4090
|
+
if (record.suite !== KEY_SUCCESSION_SUITE) return false;
|
|
1292
4091
|
const payload = keySuccessionPayload(
|
|
1293
4092
|
record.old_public_key,
|
|
1294
4093
|
record.new_public_key,
|
|
@@ -1298,20 +4097,20 @@ async function verifyKeySuccession(record, guardianPublicKeyHex) {
|
|
|
1298
4097
|
);
|
|
1299
4098
|
const message = new TextEncoder().encode(payload);
|
|
1300
4099
|
try {
|
|
1301
|
-
const newPubKey =
|
|
1302
|
-
const newSig =
|
|
1303
|
-
const newValid = await
|
|
4100
|
+
const newPubKey = hexToBytes4(record.new_public_key);
|
|
4101
|
+
const newSig = hexToBytes4(record.new_key_signature);
|
|
4102
|
+
const newValid = await verifyBySuite(record.suite, message, newSig, newPubKey);
|
|
1304
4103
|
if (!newValid) return false;
|
|
1305
4104
|
if (record.recovery) {
|
|
1306
4105
|
if (!record.guardian_signature || !guardianPublicKeyHex) return false;
|
|
1307
|
-
const guardianPubKey =
|
|
1308
|
-
const guardianSig =
|
|
1309
|
-
return await
|
|
4106
|
+
const guardianPubKey = hexToBytes4(guardianPublicKeyHex);
|
|
4107
|
+
const guardianSig = hexToBytes4(record.guardian_signature);
|
|
4108
|
+
return await verifyBySuite(record.suite, message, guardianSig, guardianPubKey);
|
|
1310
4109
|
} else {
|
|
1311
4110
|
if (!record.old_key_signature) return false;
|
|
1312
|
-
const oldPubKey =
|
|
1313
|
-
const oldSig =
|
|
1314
|
-
return await
|
|
4111
|
+
const oldPubKey = hexToBytes4(record.old_public_key);
|
|
4112
|
+
const oldSig = hexToBytes4(record.old_key_signature);
|
|
4113
|
+
return await verifyBySuite(record.suite, message, oldSig, oldPubKey);
|
|
1315
4114
|
}
|
|
1316
4115
|
} catch {
|
|
1317
4116
|
return false;
|
|
@@ -1391,34 +4190,54 @@ async function verifySuccessionChain(chain, guardianPublicKeyHex) {
|
|
|
1391
4190
|
length: chain.length
|
|
1392
4191
|
};
|
|
1393
4192
|
}
|
|
4193
|
+
var GUARDIAN_REVOCATION_SUITE = "motebit-jcs-ed25519-hex-v1";
|
|
1394
4194
|
async function signGuardianRevocation(identityPrivateKey, guardianPrivateKey, timestamp) {
|
|
1395
4195
|
const ts = timestamp ?? Date.now();
|
|
1396
|
-
const payload = canonicalJson({
|
|
4196
|
+
const payload = canonicalJson({
|
|
4197
|
+
action: "guardian_revoked",
|
|
4198
|
+
timestamp: ts,
|
|
4199
|
+
suite: GUARDIAN_REVOCATION_SUITE
|
|
4200
|
+
});
|
|
1397
4201
|
const message = new TextEncoder().encode(payload);
|
|
1398
|
-
const identitySig = await
|
|
1399
|
-
const guardianSig = await
|
|
4202
|
+
const identitySig = await signBySuite(GUARDIAN_REVOCATION_SUITE, message, identityPrivateKey);
|
|
4203
|
+
const guardianSig = await signBySuite(GUARDIAN_REVOCATION_SUITE, message, guardianPrivateKey);
|
|
1400
4204
|
return {
|
|
1401
4205
|
payload,
|
|
1402
|
-
identity_signature:
|
|
1403
|
-
guardian_signature:
|
|
4206
|
+
identity_signature: bytesToHex3(identitySig),
|
|
4207
|
+
guardian_signature: bytesToHex3(guardianSig),
|
|
1404
4208
|
timestamp: ts
|
|
1405
4209
|
};
|
|
1406
4210
|
}
|
|
1407
4211
|
async function verifyGuardianRevocation(revocation, identityPublicKeyHex, guardianPublicKeyHex) {
|
|
1408
|
-
const payload = canonicalJson({
|
|
4212
|
+
const payload = canonicalJson({
|
|
4213
|
+
action: "guardian_revoked",
|
|
4214
|
+
timestamp: revocation.timestamp,
|
|
4215
|
+
suite: GUARDIAN_REVOCATION_SUITE
|
|
4216
|
+
});
|
|
1409
4217
|
const message = new TextEncoder().encode(payload);
|
|
1410
4218
|
try {
|
|
1411
|
-
const identityPub =
|
|
1412
|
-
const guardianPub =
|
|
1413
|
-
const identitySig =
|
|
1414
|
-
const guardianSig =
|
|
1415
|
-
const identityValid = await
|
|
1416
|
-
|
|
4219
|
+
const identityPub = hexToBytes4(identityPublicKeyHex);
|
|
4220
|
+
const guardianPub = hexToBytes4(guardianPublicKeyHex);
|
|
4221
|
+
const identitySig = hexToBytes4(revocation.identity_signature);
|
|
4222
|
+
const guardianSig = hexToBytes4(revocation.guardian_signature);
|
|
4223
|
+
const identityValid = await verifyBySuite(
|
|
4224
|
+
GUARDIAN_REVOCATION_SUITE,
|
|
4225
|
+
message,
|
|
4226
|
+
identitySig,
|
|
4227
|
+
identityPub
|
|
4228
|
+
);
|
|
4229
|
+
const guardianValid = await verifyBySuite(
|
|
4230
|
+
GUARDIAN_REVOCATION_SUITE,
|
|
4231
|
+
message,
|
|
4232
|
+
guardianSig,
|
|
4233
|
+
guardianPub
|
|
4234
|
+
);
|
|
1417
4235
|
return identityValid && guardianValid;
|
|
1418
4236
|
} catch {
|
|
1419
4237
|
return false;
|
|
1420
4238
|
}
|
|
1421
4239
|
}
|
|
4240
|
+
var COLLABORATIVE_RECEIPT_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
1422
4241
|
async function signCollaborativeReceipt(receipt, initiatorPrivateKey) {
|
|
1423
4242
|
const receiptsCanonical = canonicalJson(receipt.participant_receipts);
|
|
1424
4243
|
const receiptsBytes = new TextEncoder().encode(receiptsCanonical);
|
|
@@ -1426,17 +4245,22 @@ async function signCollaborativeReceipt(receipt, initiatorPrivateKey) {
|
|
|
1426
4245
|
const sigPayload = canonicalJson({
|
|
1427
4246
|
proposal_id: receipt.proposal_id,
|
|
1428
4247
|
plan_id: receipt.plan_id,
|
|
1429
|
-
content_hash: contentHash
|
|
4248
|
+
content_hash: contentHash,
|
|
4249
|
+
suite: COLLABORATIVE_RECEIPT_SUITE
|
|
1430
4250
|
});
|
|
1431
4251
|
const sigMessage = new TextEncoder().encode(sigPayload);
|
|
1432
|
-
const sig = await
|
|
4252
|
+
const sig = await signBySuite(COLLABORATIVE_RECEIPT_SUITE, sigMessage, initiatorPrivateKey);
|
|
1433
4253
|
return {
|
|
1434
4254
|
...receipt,
|
|
1435
4255
|
content_hash: contentHash,
|
|
4256
|
+
suite: COLLABORATIVE_RECEIPT_SUITE,
|
|
1436
4257
|
initiator_signature: toBase64Url(sig)
|
|
1437
4258
|
};
|
|
1438
4259
|
}
|
|
1439
4260
|
async function verifyCollaborativeReceipt(receipt, initiatorPublicKey, participantKeys) {
|
|
4261
|
+
if (receipt.suite !== COLLABORATIVE_RECEIPT_SUITE) {
|
|
4262
|
+
return { valid: false, error: "Unknown or missing cryptosuite" };
|
|
4263
|
+
}
|
|
1440
4264
|
const receiptsCanonical = canonicalJson(receipt.participant_receipts);
|
|
1441
4265
|
const receiptsBytes = new TextEncoder().encode(receiptsCanonical);
|
|
1442
4266
|
const expectedHash = await hash(receiptsBytes);
|
|
@@ -1446,12 +4270,13 @@ async function verifyCollaborativeReceipt(receipt, initiatorPublicKey, participa
|
|
|
1446
4270
|
const sigPayload = canonicalJson({
|
|
1447
4271
|
proposal_id: receipt.proposal_id,
|
|
1448
4272
|
plan_id: receipt.plan_id,
|
|
1449
|
-
content_hash: receipt.content_hash
|
|
4273
|
+
content_hash: receipt.content_hash,
|
|
4274
|
+
suite: receipt.suite
|
|
1450
4275
|
});
|
|
1451
4276
|
const sigMessage = new TextEncoder().encode(sigPayload);
|
|
1452
4277
|
try {
|
|
1453
4278
|
const sig = fromBase64Url(receipt.initiator_signature);
|
|
1454
|
-
const sigValid = await
|
|
4279
|
+
const sigValid = await verifyBySuite(receipt.suite, sigMessage, sig, initiatorPublicKey);
|
|
1455
4280
|
if (!sigValid) {
|
|
1456
4281
|
return { valid: false, error: "Initiator signature invalid" };
|
|
1457
4282
|
}
|
|
@@ -1479,6 +4304,39 @@ async function verifyCollaborativeReceipt(receipt, initiatorPublicKey, participa
|
|
|
1479
4304
|
}
|
|
1480
4305
|
return { valid: true };
|
|
1481
4306
|
}
|
|
4307
|
+
var DEVICE_REGISTRATION_SUITE = "motebit-jcs-ed25519-b64-v1";
|
|
4308
|
+
async function signDeviceRegistration(body, privateKey) {
|
|
4309
|
+
const withSuite = { ...body, suite: DEVICE_REGISTRATION_SUITE };
|
|
4310
|
+
const canonical = canonicalJson(withSuite);
|
|
4311
|
+
const message = new TextEncoder().encode(canonical);
|
|
4312
|
+
const sig = await signBySuite(DEVICE_REGISTRATION_SUITE, message, privateKey);
|
|
4313
|
+
return { ...withSuite, signature: toBase64Url(sig) };
|
|
4314
|
+
}
|
|
4315
|
+
var DEVICE_REGISTRATION_MAX_AGE_MS = 5 * 60 * 1e3;
|
|
4316
|
+
async function verifyDeviceRegistration(body, now = Date.now()) {
|
|
4317
|
+
if (typeof body.motebit_id !== "string" || typeof body.device_id !== "string" || typeof body.public_key !== "string" || !/^[0-9a-f]{64}$/i.test(body.public_key) || typeof body.timestamp !== "number" || typeof body.suite !== "string" || typeof body.signature !== "string") {
|
|
4318
|
+
return { valid: false, reason: "malformed" };
|
|
4319
|
+
}
|
|
4320
|
+
if (Math.abs(now - body.timestamp) > DEVICE_REGISTRATION_MAX_AGE_MS) {
|
|
4321
|
+
return { valid: false, reason: "stale" };
|
|
4322
|
+
}
|
|
4323
|
+
if (body.suite !== DEVICE_REGISTRATION_SUITE) {
|
|
4324
|
+
return { valid: false, reason: "unsupported_suite" };
|
|
4325
|
+
}
|
|
4326
|
+
const { signature, ...bodyForSig } = body;
|
|
4327
|
+
const canonical = canonicalJson(bodyForSig);
|
|
4328
|
+
const message = new TextEncoder().encode(canonical);
|
|
4329
|
+
let sigBytes;
|
|
4330
|
+
let pkBytes;
|
|
4331
|
+
try {
|
|
4332
|
+
sigBytes = fromBase64Url(signature);
|
|
4333
|
+
pkBytes = hexToBytes4(body.public_key);
|
|
4334
|
+
} catch {
|
|
4335
|
+
return { valid: false, reason: "malformed" };
|
|
4336
|
+
}
|
|
4337
|
+
const ok = await verifyBySuite(body.suite, message, sigBytes, pkBytes);
|
|
4338
|
+
return ok ? { valid: true } : { valid: false, reason: "bad_signature" };
|
|
4339
|
+
}
|
|
1482
4340
|
|
|
1483
4341
|
// src/credentials.ts
|
|
1484
4342
|
function buildVerificationMethod(publicKey) {
|
|
@@ -1497,9 +4355,9 @@ async function signDataIntegrity(document, privateKey, publicKey, proofPurpose)
|
|
|
1497
4355
|
proofPurpose
|
|
1498
4356
|
};
|
|
1499
4357
|
const encoder = new TextEncoder();
|
|
1500
|
-
const proofHash = await
|
|
4358
|
+
const proofHash = await sha2563(encoder.encode(canonicalJson(proofOptions)));
|
|
1501
4359
|
const { proof: _proof, ...docWithoutProof } = document;
|
|
1502
|
-
const docHash = await
|
|
4360
|
+
const docHash = await sha2563(encoder.encode(canonicalJson(docWithoutProof)));
|
|
1503
4361
|
const combined = new Uint8Array(proofHash.length + docHash.length);
|
|
1504
4362
|
combined.set(proofHash);
|
|
1505
4363
|
combined.set(docHash, proofHash.length);
|
|
@@ -1520,9 +4378,9 @@ async function verifyDataIntegritySigning(document, proof) {
|
|
|
1520
4378
|
}
|
|
1521
4379
|
const { proofValue, ...proofOptions } = proof;
|
|
1522
4380
|
const encoder = new TextEncoder();
|
|
1523
|
-
const proofHash = await
|
|
4381
|
+
const proofHash = await sha2563(encoder.encode(canonicalJson(proofOptions)));
|
|
1524
4382
|
const { proof: _proof, ...docWithoutProof } = document;
|
|
1525
|
-
const docHash = await
|
|
4383
|
+
const docHash = await sha2563(encoder.encode(canonicalJson(docWithoutProof)));
|
|
1526
4384
|
const combined = new Uint8Array(proofHash.length + docHash.length);
|
|
1527
4385
|
combined.set(proofHash);
|
|
1528
4386
|
combined.set(docHash, proofHash.length);
|
|
@@ -1668,6 +4526,7 @@ async function createPresentation(credentials, privateKey, publicKey) {
|
|
|
1668
4526
|
}
|
|
1669
4527
|
|
|
1670
4528
|
// src/credential-anchor.ts
|
|
4529
|
+
var CREDENTIAL_ANCHOR_SUITE = "motebit-jcs-ed25519-hex-v1";
|
|
1671
4530
|
function toHex(bytes) {
|
|
1672
4531
|
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1673
4532
|
}
|
|
@@ -1686,7 +4545,7 @@ function concat(a, b) {
|
|
|
1686
4545
|
}
|
|
1687
4546
|
async function computeCredentialLeaf(credential) {
|
|
1688
4547
|
const canonical = canonicalJson(credential);
|
|
1689
|
-
const hash2 = await
|
|
4548
|
+
const hash2 = await sha2563(new TextEncoder().encode(canonical));
|
|
1690
4549
|
return toHex(hash2);
|
|
1691
4550
|
}
|
|
1692
4551
|
async function verifyMerkleInclusion(leaf, index, siblings, layerSizes, expectedRoot) {
|
|
@@ -1700,7 +4559,7 @@ async function verifyMerkleInclusion(leaf, index, siblings, layerSizes, expected
|
|
|
1700
4559
|
if (sibIdx >= siblings.length) return false;
|
|
1701
4560
|
const siblingBytes = fromHex(siblings[sibIdx]);
|
|
1702
4561
|
const combined = idx % 2 === 0 ? concat(current, siblingBytes) : concat(siblingBytes, current);
|
|
1703
|
-
current = await
|
|
4562
|
+
current = await sha2563(combined);
|
|
1704
4563
|
sibIdx++;
|
|
1705
4564
|
}
|
|
1706
4565
|
idx = Math.floor(idx / 2);
|
|
@@ -1726,25 +4585,36 @@ async function verifyCredentialAnchor(credential, anchorProof, chainVerifier) {
|
|
|
1726
4585
|
if (!merkleValid) {
|
|
1727
4586
|
errors.push("Merkle proof does not reconstruct to the claimed root");
|
|
1728
4587
|
}
|
|
1729
|
-
const
|
|
1730
|
-
batch_id: anchorProof.batch_id,
|
|
1731
|
-
merkle_root: anchorProof.merkle_root,
|
|
1732
|
-
leaf_count: anchorProof.leaf_count,
|
|
1733
|
-
first_issued_at: anchorProof.first_issued_at,
|
|
1734
|
-
last_issued_at: anchorProof.last_issued_at,
|
|
1735
|
-
relay_id: anchorProof.relay_id
|
|
1736
|
-
});
|
|
1737
|
-
const payloadBytes = new TextEncoder().encode(batchPayload);
|
|
1738
|
-
const signatureBytes = hexToBytes2(anchorProof.batch_signature);
|
|
1739
|
-
const publicKeyBytes = hexToBytes2(anchorProof.relay_public_key);
|
|
4588
|
+
const suite = anchorProof.suite;
|
|
1740
4589
|
let relaySignatureValid = false;
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
}
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
4590
|
+
if (suite !== CREDENTIAL_ANCHOR_SUITE) {
|
|
4591
|
+
errors.push(`Relay batch signature: missing or unsupported suite "${String(suite)}"`);
|
|
4592
|
+
} else {
|
|
4593
|
+
const batchPayload = canonicalJson({
|
|
4594
|
+
batch_id: anchorProof.batch_id,
|
|
4595
|
+
merkle_root: anchorProof.merkle_root,
|
|
4596
|
+
leaf_count: anchorProof.leaf_count,
|
|
4597
|
+
first_issued_at: anchorProof.first_issued_at,
|
|
4598
|
+
last_issued_at: anchorProof.last_issued_at,
|
|
4599
|
+
relay_id: anchorProof.relay_id,
|
|
4600
|
+
suite
|
|
4601
|
+
});
|
|
4602
|
+
const payloadBytes = new TextEncoder().encode(batchPayload);
|
|
4603
|
+
const signatureBytes = hexToBytes4(anchorProof.batch_signature);
|
|
4604
|
+
const publicKeyBytes = hexToBytes4(anchorProof.relay_public_key);
|
|
4605
|
+
try {
|
|
4606
|
+
relaySignatureValid = await verifyBySuite(
|
|
4607
|
+
suite,
|
|
4608
|
+
payloadBytes,
|
|
4609
|
+
signatureBytes,
|
|
4610
|
+
publicKeyBytes
|
|
4611
|
+
);
|
|
4612
|
+
} catch {
|
|
4613
|
+
relaySignatureValid = false;
|
|
4614
|
+
}
|
|
4615
|
+
if (!relaySignatureValid) {
|
|
4616
|
+
errors.push("Relay batch signature verification failed");
|
|
4617
|
+
}
|
|
1748
4618
|
}
|
|
1749
4619
|
let chainVerified = null;
|
|
1750
4620
|
if (anchorProof.anchor && chainVerifier) {
|
|
@@ -1775,11 +4645,69 @@ async function verifyCredentialAnchor(credential, anchorProof, chainVerifier) {
|
|
|
1775
4645
|
errors
|
|
1776
4646
|
};
|
|
1777
4647
|
}
|
|
4648
|
+
var REVOCATION_ANCHOR_SUITE = "motebit-concat-ed25519-hex-v1";
|
|
4649
|
+
async function verifyRevocationAnchor(proof, revocationPayload, chainVerifier) {
|
|
4650
|
+
const errors = [];
|
|
4651
|
+
const expectedMemo = `motebit:revocation:v1:${proof.revoked_public_key}:${proof.timestamp}`;
|
|
4652
|
+
const memoValid = proof.revoked_public_key.length === 64 && proof.timestamp > 0;
|
|
4653
|
+
if (!memoValid) {
|
|
4654
|
+
errors.push(
|
|
4655
|
+
`Invalid revocation proof: public key length ${proof.revoked_public_key.length} (expected 64), timestamp ${proof.timestamp}`
|
|
4656
|
+
);
|
|
4657
|
+
}
|
|
4658
|
+
let relaySignatureValid = false;
|
|
4659
|
+
if (proof.suite !== REVOCATION_ANCHOR_SUITE) {
|
|
4660
|
+
errors.push(
|
|
4661
|
+
`Relay revocation signature: missing or unsupported suite "${String(proof.suite)}"`
|
|
4662
|
+
);
|
|
4663
|
+
} else {
|
|
4664
|
+
const payloadBytes = new TextEncoder().encode(revocationPayload);
|
|
4665
|
+
const signatureBytes = hexToBytes4(proof.signature);
|
|
4666
|
+
const publicKeyBytes = hexToBytes4(proof.relay_public_key);
|
|
4667
|
+
try {
|
|
4668
|
+
relaySignatureValid = await verifyBySuite(
|
|
4669
|
+
proof.suite,
|
|
4670
|
+
payloadBytes,
|
|
4671
|
+
signatureBytes,
|
|
4672
|
+
publicKeyBytes
|
|
4673
|
+
);
|
|
4674
|
+
} catch {
|
|
4675
|
+
relaySignatureValid = false;
|
|
4676
|
+
}
|
|
4677
|
+
if (!relaySignatureValid) {
|
|
4678
|
+
errors.push("Relay revocation signature verification failed");
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4681
|
+
let chainVerified = null;
|
|
4682
|
+
if (proof.anchor && chainVerifier) {
|
|
4683
|
+
try {
|
|
4684
|
+
chainVerified = await chainVerifier({
|
|
4685
|
+
...proof.anchor,
|
|
4686
|
+
expected_memo: expectedMemo
|
|
4687
|
+
});
|
|
4688
|
+
if (!chainVerified) {
|
|
4689
|
+
errors.push("Onchain revocation anchor verification failed");
|
|
4690
|
+
}
|
|
4691
|
+
} catch (err2) {
|
|
4692
|
+
chainVerified = false;
|
|
4693
|
+
errors.push(
|
|
4694
|
+
`Onchain revocation verification error: ${err2 instanceof Error ? err2.message : String(err2)}`
|
|
4695
|
+
);
|
|
4696
|
+
}
|
|
4697
|
+
}
|
|
4698
|
+
const valid = memoValid && relaySignatureValid && (chainVerified === null || chainVerified);
|
|
4699
|
+
return {
|
|
4700
|
+
valid,
|
|
4701
|
+
steps: {
|
|
4702
|
+
memo_valid: memoValid,
|
|
4703
|
+
relay_signature_valid: relaySignatureValid,
|
|
4704
|
+
chain_verified: chainVerified
|
|
4705
|
+
},
|
|
4706
|
+
errors
|
|
4707
|
+
};
|
|
4708
|
+
}
|
|
1778
4709
|
|
|
1779
4710
|
// src/index.ts
|
|
1780
|
-
if (!hashes.sha512) {
|
|
1781
|
-
hashes.sha512 = (msg) => sha512(msg);
|
|
1782
|
-
}
|
|
1783
4711
|
function parseYamlValue(raw) {
|
|
1784
4712
|
const trimmed = raw.trim();
|
|
1785
4713
|
if (trimmed === "null") return null;
|
|
@@ -1880,7 +4808,7 @@ function parseYaml(text) {
|
|
|
1880
4808
|
}
|
|
1881
4809
|
return root;
|
|
1882
4810
|
}
|
|
1883
|
-
function
|
|
4811
|
+
function hexToBytes5(hex) {
|
|
1884
4812
|
const bytes = new Uint8Array(hex.length / 2);
|
|
1885
4813
|
for (let i = 0; i < hex.length; i += 2) {
|
|
1886
4814
|
bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
|
|
@@ -1973,11 +4901,12 @@ function didKeyToPublicKey2(did) {
|
|
|
1973
4901
|
}
|
|
1974
4902
|
return decoded.slice(2);
|
|
1975
4903
|
}
|
|
1976
|
-
async function
|
|
4904
|
+
async function sha2564(data) {
|
|
1977
4905
|
const buf = await crypto.subtle.digest("SHA-256", data);
|
|
1978
4906
|
return new Uint8Array(buf);
|
|
1979
4907
|
}
|
|
1980
|
-
var
|
|
4908
|
+
var IDENTITY_FILE_SUITE = "motebit-jcs-ed25519-hex-v1";
|
|
4909
|
+
var SIG_PREFIX = `<!-- motebit:sig:${IDENTITY_FILE_SUITE}:`;
|
|
1981
4910
|
var SIG_SUFFIX = " -->";
|
|
1982
4911
|
function detectArtifactType(artifact) {
|
|
1983
4912
|
if (typeof artifact === "string") {
|
|
@@ -2013,7 +4942,16 @@ function parse(content) {
|
|
|
2013
4942
|
const rawFrontmatter = content.slice(bodyStart, secondDash);
|
|
2014
4943
|
const frontmatter = parseYaml(rawFrontmatter);
|
|
2015
4944
|
const sigStart = content.indexOf(SIG_PREFIX);
|
|
2016
|
-
if (sigStart === -1)
|
|
4945
|
+
if (sigStart === -1) {
|
|
4946
|
+
if (content.includes("<!-- motebit:sig:Ed25519:")) {
|
|
4947
|
+
throw new Error(
|
|
4948
|
+
`Legacy identity-file signature format detected (motebit:sig:Ed25519:). Re-sign under ${IDENTITY_FILE_SUITE} \u2014 no legacy fallback.`
|
|
4949
|
+
);
|
|
4950
|
+
}
|
|
4951
|
+
throw new Error(
|
|
4952
|
+
`Missing signature comment (expected <!-- motebit:sig:${IDENTITY_FILE_SUITE}:\u2026 -->)`
|
|
4953
|
+
);
|
|
4954
|
+
}
|
|
2017
4955
|
const sigValueStart = sigStart + SIG_PREFIX.length;
|
|
2018
4956
|
const sigEnd = content.indexOf(SIG_SUFFIX, sigValueStart);
|
|
2019
4957
|
if (sigEnd === -1) throw new Error("Malformed signature");
|
|
@@ -2037,7 +4975,7 @@ async function verifyIdentity(content) {
|
|
|
2037
4975
|
}
|
|
2038
4976
|
let pubKey;
|
|
2039
4977
|
try {
|
|
2040
|
-
pubKey =
|
|
4978
|
+
pubKey = hexToBytes5(pubKeyHex);
|
|
2041
4979
|
} catch {
|
|
2042
4980
|
return identityError("Invalid public key hex");
|
|
2043
4981
|
}
|
|
@@ -2046,7 +4984,7 @@ async function verifyIdentity(content) {
|
|
|
2046
4984
|
}
|
|
2047
4985
|
let sigBytes;
|
|
2048
4986
|
try {
|
|
2049
|
-
sigBytes =
|
|
4987
|
+
sigBytes = hexToBytes5(parsed.signature);
|
|
2050
4988
|
} catch {
|
|
2051
4989
|
return identityError("Invalid signature encoding");
|
|
2052
4990
|
}
|
|
@@ -2054,12 +4992,12 @@ async function verifyIdentity(content) {
|
|
|
2054
4992
|
return identityError("Signature must be 64 bytes");
|
|
2055
4993
|
}
|
|
2056
4994
|
const frontmatterBytes = new TextEncoder().encode(parsed.rawFrontmatter);
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
4995
|
+
const valid = await verifyBySuite(
|
|
4996
|
+
"motebit-jcs-ed25519-hex-v1",
|
|
4997
|
+
frontmatterBytes,
|
|
4998
|
+
sigBytes,
|
|
4999
|
+
pubKey
|
|
5000
|
+
);
|
|
2063
5001
|
if (!valid) {
|
|
2064
5002
|
return identityError("Signature verification failed");
|
|
2065
5003
|
}
|
|
@@ -2074,7 +5012,7 @@ async function verifyIdentity(content) {
|
|
|
2074
5012
|
const attestMessage = new TextEncoder().encode(attestPayload);
|
|
2075
5013
|
let guardianPubKey;
|
|
2076
5014
|
try {
|
|
2077
|
-
guardianPubKey =
|
|
5015
|
+
guardianPubKey = hexToBytes5(guardian.public_key);
|
|
2078
5016
|
} catch {
|
|
2079
5017
|
return identityError("Invalid guardian public key hex");
|
|
2080
5018
|
}
|
|
@@ -2083,16 +5021,16 @@ async function verifyIdentity(content) {
|
|
|
2083
5021
|
}
|
|
2084
5022
|
let attestSig;
|
|
2085
5023
|
try {
|
|
2086
|
-
attestSig =
|
|
5024
|
+
attestSig = hexToBytes5(guardian.attestation);
|
|
2087
5025
|
} catch {
|
|
2088
5026
|
return identityError("Invalid guardian attestation encoding");
|
|
2089
5027
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
5028
|
+
const attestValid = await verifyBySuite(
|
|
5029
|
+
"motebit-jcs-ed25519-hex-v1",
|
|
5030
|
+
attestMessage,
|
|
5031
|
+
attestSig,
|
|
5032
|
+
guardianPubKey
|
|
5033
|
+
);
|
|
2096
5034
|
if (!attestValid) {
|
|
2097
5035
|
return identityError("Guardian attestation signature verification failed");
|
|
2098
5036
|
}
|
|
@@ -2115,10 +5053,18 @@ async function verifySuccessionChain2(chain, currentPublicKeyHex, guardianPublic
|
|
|
2115
5053
|
try {
|
|
2116
5054
|
for (let i = 0; i < chain.length; i++) {
|
|
2117
5055
|
const record = chain[i];
|
|
5056
|
+
if (record.suite !== "motebit-jcs-ed25519-hex-v1") {
|
|
5057
|
+
return {
|
|
5058
|
+
valid: false,
|
|
5059
|
+
rotations: chain.length,
|
|
5060
|
+
error: `Succession record ${i}: missing or invalid suite (expected motebit-jcs-ed25519-hex-v1)`
|
|
5061
|
+
};
|
|
5062
|
+
}
|
|
2118
5063
|
const payloadObj = {
|
|
2119
5064
|
old_public_key: record.old_public_key,
|
|
2120
5065
|
new_public_key: record.new_public_key,
|
|
2121
|
-
timestamp: record.timestamp
|
|
5066
|
+
timestamp: record.timestamp,
|
|
5067
|
+
suite: "motebit-jcs-ed25519-hex-v1"
|
|
2122
5068
|
};
|
|
2123
5069
|
if (record.reason !== void 0) {
|
|
2124
5070
|
payloadObj.reason = record.reason;
|
|
@@ -2128,9 +5074,14 @@ async function verifySuccessionChain2(chain, currentPublicKeyHex, guardianPublic
|
|
|
2128
5074
|
}
|
|
2129
5075
|
const payload = canonicalJson2(payloadObj);
|
|
2130
5076
|
const message = new TextEncoder().encode(payload);
|
|
2131
|
-
const newPubKey =
|
|
2132
|
-
const newSig =
|
|
2133
|
-
const newValid = await
|
|
5077
|
+
const newPubKey = hexToBytes5(record.new_public_key);
|
|
5078
|
+
const newSig = hexToBytes5(record.new_key_signature);
|
|
5079
|
+
const newValid = await verifyBySuite(
|
|
5080
|
+
"motebit-jcs-ed25519-hex-v1",
|
|
5081
|
+
message,
|
|
5082
|
+
newSig,
|
|
5083
|
+
newPubKey
|
|
5084
|
+
);
|
|
2134
5085
|
if (!newValid) {
|
|
2135
5086
|
return {
|
|
2136
5087
|
valid: false,
|
|
@@ -2153,9 +5104,14 @@ async function verifySuccessionChain2(chain, currentPublicKeyHex, guardianPublic
|
|
|
2153
5104
|
error: `Succession record ${i}: guardian recovery but no guardian_signature`
|
|
2154
5105
|
};
|
|
2155
5106
|
}
|
|
2156
|
-
const guardianPubKey =
|
|
2157
|
-
const guardianSig =
|
|
2158
|
-
const guardianValid = await
|
|
5107
|
+
const guardianPubKey = hexToBytes5(guardianPublicKeyHex);
|
|
5108
|
+
const guardianSig = hexToBytes5(record.guardian_signature);
|
|
5109
|
+
const guardianValid = await verifyBySuite(
|
|
5110
|
+
"motebit-jcs-ed25519-hex-v1",
|
|
5111
|
+
message,
|
|
5112
|
+
guardianSig,
|
|
5113
|
+
guardianPubKey
|
|
5114
|
+
);
|
|
2159
5115
|
if (!guardianValid) {
|
|
2160
5116
|
return {
|
|
2161
5117
|
valid: false,
|
|
@@ -2171,9 +5127,14 @@ async function verifySuccessionChain2(chain, currentPublicKeyHex, guardianPublic
|
|
|
2171
5127
|
error: `Succession record ${i}: normal rotation but no old_key_signature`
|
|
2172
5128
|
};
|
|
2173
5129
|
}
|
|
2174
|
-
const oldPubKey =
|
|
2175
|
-
const oldSig =
|
|
2176
|
-
const oldValid = await
|
|
5130
|
+
const oldPubKey = hexToBytes5(record.old_public_key);
|
|
5131
|
+
const oldSig = hexToBytes5(record.old_key_signature);
|
|
5132
|
+
const oldValid = await verifyBySuite(
|
|
5133
|
+
"motebit-jcs-ed25519-hex-v1",
|
|
5134
|
+
message,
|
|
5135
|
+
oldSig,
|
|
5136
|
+
oldPubKey
|
|
5137
|
+
);
|
|
2177
5138
|
if (!oldValid) {
|
|
2178
5139
|
return {
|
|
2179
5140
|
valid: false,
|
|
@@ -2241,19 +5202,15 @@ async function verifyReceiptSignature(receipt, publicKey) {
|
|
|
2241
5202
|
}
|
|
2242
5203
|
const canonical = canonicalJson2(body);
|
|
2243
5204
|
const message = new TextEncoder().encode(canonical);
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
return { valid };
|
|
2247
|
-
} catch {
|
|
2248
|
-
return { valid: false, error: "Ed25519 verification threw" };
|
|
2249
|
-
}
|
|
5205
|
+
const valid = await verifyBySuite("motebit-jcs-ed25519-b64-v1", message, sig, publicKey);
|
|
5206
|
+
return { valid };
|
|
2250
5207
|
}
|
|
2251
5208
|
async function verifyReceipt(receipt) {
|
|
2252
5209
|
let publicKey = null;
|
|
2253
5210
|
let signerDid;
|
|
2254
5211
|
if (receipt.public_key) {
|
|
2255
5212
|
try {
|
|
2256
|
-
publicKey =
|
|
5213
|
+
publicKey = hexToBytes5(receipt.public_key);
|
|
2257
5214
|
if (publicKey.length === 32) {
|
|
2258
5215
|
signerDid = publicKeyToDidKey2(publicKey);
|
|
2259
5216
|
} else {
|
|
@@ -2314,9 +5271,9 @@ async function verifyDataIntegrity(document, proof) {
|
|
|
2314
5271
|
}
|
|
2315
5272
|
const { proofValue, ...proofOptions } = proof;
|
|
2316
5273
|
const encoder = new TextEncoder();
|
|
2317
|
-
const proofHash = await
|
|
5274
|
+
const proofHash = await sha2564(encoder.encode(canonicalJson2(proofOptions)));
|
|
2318
5275
|
const { proof: _proof, ...docWithoutProof } = document;
|
|
2319
|
-
const docHash = await
|
|
5276
|
+
const docHash = await sha2564(encoder.encode(canonicalJson2(docWithoutProof)));
|
|
2320
5277
|
const combined = new Uint8Array(proofHash.length + docHash.length);
|
|
2321
5278
|
combined.set(proofHash);
|
|
2322
5279
|
combined.set(docHash, proofHash.length);
|
|
@@ -2327,14 +5284,10 @@ async function verifyDataIntegrity(document, proof) {
|
|
|
2327
5284
|
} catch {
|
|
2328
5285
|
return false;
|
|
2329
5286
|
}
|
|
2330
|
-
|
|
2331
|
-
return await verifyAsync(signature, combined, publicKey);
|
|
2332
|
-
} catch {
|
|
2333
|
-
return false;
|
|
2334
|
-
}
|
|
5287
|
+
return verifyBySuite("eddsa-jcs-2022", combined, signature, publicKey);
|
|
2335
5288
|
}
|
|
2336
5289
|
var DEFAULT_CLOCK_SKEW_SECONDS = 60;
|
|
2337
|
-
async function verifyCredential(vc, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECONDS) {
|
|
5290
|
+
async function verifyCredential(vc, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECONDS, hardwareAttestationVerifiers) {
|
|
2338
5291
|
const errors = [];
|
|
2339
5292
|
let expired = false;
|
|
2340
5293
|
if (vc.validUntil) {
|
|
@@ -2351,6 +5304,21 @@ async function verifyCredential(vc, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECOND
|
|
|
2351
5304
|
}
|
|
2352
5305
|
const issuerDid = typeof vc.issuer === "string" ? vc.issuer : void 0;
|
|
2353
5306
|
const subjectId = vc.credentialSubject?.id;
|
|
5307
|
+
const subject = vc.credentialSubject;
|
|
5308
|
+
let hardwareAttestation;
|
|
5309
|
+
if (subject !== void 0 && subject.hardware_attestation !== void 0 && subject.hardware_attestation !== null && typeof subject.hardware_attestation === "object" && typeof subject.identity_public_key === "string") {
|
|
5310
|
+
const deviceCheckContext = {
|
|
5311
|
+
...typeof subject.motebit_id === "string" ? { expectedMotebitId: subject.motebit_id } : {},
|
|
5312
|
+
...typeof subject.device_id === "string" ? { expectedDeviceId: subject.device_id } : {},
|
|
5313
|
+
...typeof subject.attested_at === "number" ? { expectedAttestedAt: subject.attested_at } : {}
|
|
5314
|
+
};
|
|
5315
|
+
hardwareAttestation = await verifyHardwareAttestationClaim(
|
|
5316
|
+
subject.hardware_attestation,
|
|
5317
|
+
subject.identity_public_key,
|
|
5318
|
+
hardwareAttestationVerifiers,
|
|
5319
|
+
deviceCheckContext
|
|
5320
|
+
);
|
|
5321
|
+
}
|
|
2354
5322
|
return {
|
|
2355
5323
|
type: "credential",
|
|
2356
5324
|
valid: proofValid && !expired,
|
|
@@ -2358,10 +5326,11 @@ async function verifyCredential(vc, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECOND
|
|
|
2358
5326
|
issuer: issuerDid,
|
|
2359
5327
|
subject: subjectId,
|
|
2360
5328
|
expired,
|
|
5329
|
+
...hardwareAttestation && { hardware_attestation: hardwareAttestation },
|
|
2361
5330
|
...errors.length > 0 ? { errors } : {}
|
|
2362
5331
|
};
|
|
2363
5332
|
}
|
|
2364
|
-
async function verifyPresentation(vp, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECONDS) {
|
|
5333
|
+
async function verifyPresentation(vp, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECONDS, hardwareAttestationVerifiers) {
|
|
2365
5334
|
const errors = [];
|
|
2366
5335
|
const envelopeValid = await verifyDataIntegrity(
|
|
2367
5336
|
vp,
|
|
@@ -2373,7 +5342,7 @@ async function verifyPresentation(vp, clockSkewSeconds = DEFAULT_CLOCK_SKEW_SECO
|
|
|
2373
5342
|
const credentialResults = [];
|
|
2374
5343
|
for (let i = 0; i < vp.verifiableCredential.length; i++) {
|
|
2375
5344
|
const vc = vp.verifiableCredential[i];
|
|
2376
|
-
const vcResult = await verifyCredential(vc, clockSkewSeconds);
|
|
5345
|
+
const vcResult = await verifyCredential(vc, clockSkewSeconds, hardwareAttestationVerifiers);
|
|
2377
5346
|
credentialResults.push(vcResult);
|
|
2378
5347
|
if (!vcResult.valid) {
|
|
2379
5348
|
errors.push({
|
|
@@ -2438,9 +5407,17 @@ async function verify(artifact, options) {
|
|
|
2438
5407
|
case "receipt":
|
|
2439
5408
|
return verifyReceipt(resolved);
|
|
2440
5409
|
case "credential":
|
|
2441
|
-
return verifyCredential(
|
|
5410
|
+
return verifyCredential(
|
|
5411
|
+
resolved,
|
|
5412
|
+
options?.clockSkewSeconds,
|
|
5413
|
+
options?.hardwareAttestation
|
|
5414
|
+
);
|
|
2442
5415
|
case "presentation":
|
|
2443
|
-
return verifyPresentation(
|
|
5416
|
+
return verifyPresentation(
|
|
5417
|
+
resolved,
|
|
5418
|
+
options?.clockSkewSeconds,
|
|
5419
|
+
options?.hardwareAttestation
|
|
5420
|
+
);
|
|
2444
5421
|
}
|
|
2445
5422
|
}
|
|
2446
5423
|
async function verifyIdentityFile(content) {
|
|
@@ -2454,21 +5431,44 @@ async function verifyIdentityFile(content) {
|
|
|
2454
5431
|
};
|
|
2455
5432
|
}
|
|
2456
5433
|
export {
|
|
5434
|
+
ADJUDICATOR_VOTE_SUITE,
|
|
5435
|
+
BALANCE_WAIVER_SUITE,
|
|
5436
|
+
COLLABORATIVE_RECEIPT_SUITE,
|
|
5437
|
+
CONSOLIDATION_RECEIPT_SUITE,
|
|
5438
|
+
DELEGATION_TOKEN_SUITE,
|
|
5439
|
+
DEVICE_REGISTRATION_MAX_AGE_MS,
|
|
5440
|
+
DEVICE_REGISTRATION_SUITE,
|
|
5441
|
+
DISPUTE_APPEAL_SUITE,
|
|
5442
|
+
DISPUTE_EVIDENCE_SUITE,
|
|
5443
|
+
DISPUTE_REQUEST_SUITE,
|
|
5444
|
+
DISPUTE_RESOLUTION_SUITE,
|
|
5445
|
+
EXECUTION_RECEIPT_SUITE,
|
|
5446
|
+
GUARDIAN_REVOCATION_SUITE,
|
|
5447
|
+
KEY_SUCCESSION_SUITE,
|
|
5448
|
+
SETTLEMENT_RECORD_SUITE,
|
|
5449
|
+
SIGNED_TOKEN_SUITE,
|
|
5450
|
+
TOOL_INVOCATION_RECEIPT_SUITE,
|
|
2457
5451
|
base58btcDecode,
|
|
2458
5452
|
base58btcEncode,
|
|
2459
|
-
|
|
5453
|
+
bytesToHex3 as bytesToHex,
|
|
2460
5454
|
canonicalJson,
|
|
5455
|
+
canonicalSecureEnclaveBodyForTest,
|
|
5456
|
+
canonicalSha256,
|
|
2461
5457
|
computeCredentialLeaf,
|
|
2462
5458
|
createPresentation,
|
|
2463
5459
|
createSignedToken,
|
|
2464
5460
|
didKeyToPublicKey,
|
|
2465
5461
|
ed25519Sign,
|
|
2466
5462
|
ed25519Verify,
|
|
5463
|
+
encodeSecureEnclaveReceiptForTest,
|
|
2467
5464
|
fromBase64Url,
|
|
5465
|
+
generateEd25519Keypair,
|
|
2468
5466
|
generateKeypair,
|
|
5467
|
+
getPublicKeyBySuite,
|
|
2469
5468
|
hash,
|
|
5469
|
+
hashToolPayload,
|
|
2470
5470
|
hexPublicKeyToDidKey,
|
|
2471
|
-
|
|
5471
|
+
hexToBytes4 as hexToBytes,
|
|
2472
5472
|
isScopeNarrowed,
|
|
2473
5473
|
issueGradientCredential,
|
|
2474
5474
|
issueReputationCredential,
|
|
@@ -2476,30 +5476,55 @@ export {
|
|
|
2476
5476
|
parse,
|
|
2477
5477
|
parseScopeSet,
|
|
2478
5478
|
publicKeyToDidKey,
|
|
2479
|
-
sha256,
|
|
5479
|
+
sha2563 as sha256,
|
|
5480
|
+
signAdjudicatorVote,
|
|
5481
|
+
signBalanceWaiver,
|
|
5482
|
+
signBySuite,
|
|
2480
5483
|
signCollaborativeReceipt,
|
|
5484
|
+
signConsolidationReceipt,
|
|
2481
5485
|
signDelegation,
|
|
5486
|
+
signDeviceRegistration,
|
|
5487
|
+
signDisputeAppeal,
|
|
5488
|
+
signDisputeEvidence,
|
|
5489
|
+
signDisputeRequest,
|
|
5490
|
+
signDisputeResolution,
|
|
2482
5491
|
signExecutionReceipt,
|
|
2483
5492
|
signGuardianRecoverySuccession,
|
|
2484
5493
|
signGuardianRevocation,
|
|
2485
5494
|
signKeySuccession,
|
|
5495
|
+
signSettlement,
|
|
2486
5496
|
signSovereignPaymentReceipt,
|
|
5497
|
+
signToolInvocationReceipt,
|
|
2487
5498
|
signVerifiableCredential,
|
|
2488
5499
|
signVerifiablePresentation,
|
|
2489
5500
|
toBase64Url,
|
|
2490
5501
|
verify,
|
|
5502
|
+
verifyAdjudicatorVote,
|
|
5503
|
+
verifyBalanceWaiver,
|
|
5504
|
+
verifyBySuite,
|
|
2491
5505
|
verifyCollaborativeReceipt,
|
|
5506
|
+
verifyConsolidationReceipt,
|
|
2492
5507
|
verifyCredentialAnchor,
|
|
2493
5508
|
verifyDelegation,
|
|
2494
5509
|
verifyDelegationChain,
|
|
5510
|
+
verifyDeviceRegistration,
|
|
5511
|
+
verifyDisputeAppeal,
|
|
5512
|
+
verifyDisputeEvidence,
|
|
5513
|
+
verifyDisputeRequest,
|
|
5514
|
+
verifyDisputeResolution,
|
|
2495
5515
|
verifyExecutionReceipt,
|
|
5516
|
+
verifyExecutionReceiptDetailed,
|
|
2496
5517
|
verifyGuardianRevocation,
|
|
5518
|
+
verifyHardwareAttestationClaim,
|
|
2497
5519
|
verifyIdentityFile,
|
|
2498
5520
|
verifyKeySuccession,
|
|
2499
5521
|
verifyReceiptChain,
|
|
2500
5522
|
verifyReceiptSequence,
|
|
5523
|
+
verifyRevocationAnchor,
|
|
5524
|
+
verifySettlement,
|
|
2501
5525
|
verifySignedToken,
|
|
2502
5526
|
verifySuccessionChain,
|
|
5527
|
+
verifyToolInvocationReceipt,
|
|
2503
5528
|
verifyVerifiableCredential,
|
|
2504
5529
|
verifyVerifiablePresentation
|
|
2505
5530
|
};
|
|
@@ -2508,6 +5533,15 @@ export {
|
|
|
2508
5533
|
@noble/ed25519/index.js:
|
|
2509
5534
|
(*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
|
|
2510
5535
|
|
|
5536
|
+
@noble/hashes/esm/utils.js:
|
|
2511
5537
|
@noble/hashes/esm/utils.js:
|
|
2512
5538
|
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
5539
|
+
|
|
5540
|
+
@noble/curves/esm/abstract/utils.js:
|
|
5541
|
+
@noble/curves/esm/abstract/modular.js:
|
|
5542
|
+
@noble/curves/esm/abstract/curve.js:
|
|
5543
|
+
@noble/curves/esm/abstract/weierstrass.js:
|
|
5544
|
+
@noble/curves/esm/_shortw_utils.js:
|
|
5545
|
+
@noble/curves/esm/p256.js:
|
|
5546
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
2513
5547
|
*/
|