@0xpolygonid/js-sdk 1.19.0 → 1.20.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.
@@ -2031,10 +2031,16 @@ function randomBytes$1(bytesLength = 32) {
2031
2031
  if (crypto$3 && typeof crypto$3.getRandomValues === 'function') {
2032
2032
  return crypto$3.getRandomValues(new Uint8Array(bytesLength));
2033
2033
  }
2034
+ // Legacy Node.js compatibility
2035
+ if (crypto$3 && typeof crypto$3.randomBytes === 'function') {
2036
+ return crypto$3.randomBytes(bytesLength);
2037
+ }
2034
2038
  throw new Error('crypto.getRandomValues must be defined');
2035
2039
  }
2036
2040
 
2037
- // Polyfill for Safari 14
2041
+ /**
2042
+ * Polyfill for Safari 14
2043
+ */
2038
2044
  function setBigUint64$1(view, byteOffset, value, isLE) {
2039
2045
  if (typeof view.setBigUint64 === 'function')
2040
2046
  return view.setBigUint64(byteOffset, value, isLE);
@@ -2047,9 +2053,13 @@ function setBigUint64$1(view, byteOffset, value, isLE) {
2047
2053
  view.setUint32(byteOffset + h, wh, isLE);
2048
2054
  view.setUint32(byteOffset + l, wl, isLE);
2049
2055
  }
2050
- // Choice: a ? b : c
2056
+ /**
2057
+ * Choice: a ? b : c
2058
+ */
2051
2059
  const Chi$1 = (a, b, c) => (a & b) ^ (~a & c);
2052
- // Majority function, true if any two inpust is true
2060
+ /**
2061
+ * Majority function, true if any two inputs is true
2062
+ */
2053
2063
  const Maj$1 = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
2054
2064
  /**
2055
2065
  * Merkle-Damgard hash construction base class.
@@ -3239,6 +3249,60 @@ function wNAF$1(c, bits) {
3239
3249
  },
3240
3250
  };
3241
3251
  }
3252
+ /**
3253
+ * Pippenger algorithm for multi-scalar multiplication (MSM).
3254
+ * MSM is basically (Pa + Qb + Rc + ...).
3255
+ * 30x faster vs naive addition on L=4096, 10x faster with precomputes.
3256
+ * For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
3257
+ * Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
3258
+ * @param c Curve Point constructor
3259
+ * @param field field over CURVE.N - important that it's not over CURVE.P
3260
+ * @param points array of L curve points
3261
+ * @param scalars array of L scalars (aka private keys / bigints)
3262
+ */
3263
+ function pippenger(c, field, points, scalars) {
3264
+ // If we split scalars by some window (let's say 8 bits), every chunk will only
3265
+ // take 256 buckets even if there are 4096 scalars, also re-uses double.
3266
+ // TODO:
3267
+ // - https://eprint.iacr.org/2024/750.pdf
3268
+ // - https://tches.iacr.org/index.php/TCHES/article/view/10287
3269
+ // 0 is accepted in scalars
3270
+ if (!Array.isArray(points) || !Array.isArray(scalars) || scalars.length !== points.length)
3271
+ throw new Error('arrays of points and scalars must have equal length');
3272
+ scalars.forEach((s, i) => {
3273
+ if (!field.isValid(s))
3274
+ throw new Error(`wrong scalar at index ${i}`);
3275
+ });
3276
+ points.forEach((p, i) => {
3277
+ if (!(p instanceof c))
3278
+ throw new Error(`wrong point at index ${i}`);
3279
+ });
3280
+ const wbits = bitLen$1(BigInt(points.length));
3281
+ const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
3282
+ const MASK = (1 << windowSize) - 1;
3283
+ const buckets = new Array(MASK + 1).fill(c.ZERO); // +1 for zero array
3284
+ const lastBits = Math.floor((field.BITS - 1) / windowSize) * windowSize;
3285
+ let sum = c.ZERO;
3286
+ for (let i = lastBits; i >= 0; i -= windowSize) {
3287
+ buckets.fill(c.ZERO);
3288
+ for (let j = 0; j < scalars.length; j++) {
3289
+ const scalar = scalars[j];
3290
+ const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
3291
+ buckets[wbits] = buckets[wbits].add(points[j]);
3292
+ }
3293
+ let resI = c.ZERO; // not using this will do small speed-up, but will lose ct
3294
+ // Skip first bucket, because it is zero
3295
+ for (let j = buckets.length - 1, sumI = c.ZERO; j > 0; j--) {
3296
+ sumI = sumI.add(buckets[j]);
3297
+ resI = resI.add(sumI);
3298
+ }
3299
+ sum = sum.add(resI);
3300
+ if (i !== 0)
3301
+ for (let j = 0; j < windowSize; j++)
3302
+ sum = sum.double();
3303
+ }
3304
+ return sum;
3305
+ }
3242
3306
  function validateBasic$1(curve) {
3243
3307
  validateField$1(curve.Fp);
3244
3308
  validateObject$1(curve, {
@@ -3293,6 +3357,7 @@ function twistedEdwards(curveDef) {
3293
3357
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
3294
3358
  const MASK = _2n$7 << (BigInt(nByteLength * 8) - _1n$a);
3295
3359
  const modP = Fp.create; // Function overrides
3360
+ const Fn = Field$1(CURVE.n, CURVE.nBitLength);
3296
3361
  // sqrt(u/v)
3297
3362
  const uvRatio = CURVE.uvRatio ||
3298
3363
  ((u, v) => {
@@ -3391,6 +3456,10 @@ function twistedEdwards(curveDef) {
3391
3456
  const toInv = Fp.invertBatch(points.map((p) => p.ez));
3392
3457
  return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
3393
3458
  }
3459
+ // Multiscalar Multiplication
3460
+ static msm(points, scalars) {
3461
+ return pippenger(Point, Fn, points, scalars);
3462
+ }
3394
3463
  // "Private method", don't use it directly
3395
3464
  _setWindowSize(windowSize) {
3396
3465
  wnaf.setWindowSize(this, windowSize);
@@ -4040,6 +4109,10 @@ let HMAC$1 = class HMAC extends Hash$1 {
4040
4109
  * @param hash - function that would be used e.g. sha256
4041
4110
  * @param key - message key
4042
4111
  * @param message - message data
4112
+ * @example
4113
+ * import { hmac } from '@noble/hashes/hmac';
4114
+ * import { sha256 } from '@noble/hashes/sha2';
4115
+ * const mac1 = hmac(sha256, 'key', 'message');
4043
4116
  */
4044
4117
  const hmac$1 = (hash, key, message) => new HMAC$1(hash, key).update(message).digest();
4045
4118
  hmac$1.create = (hash, key) => new HMAC$1(hash, key);
@@ -4079,8 +4152,14 @@ function validatePointOpts$1(curve) {
4079
4152
  }
4080
4153
  return Object.freeze({ ...opts });
4081
4154
  }
4082
- // ASN.1 DER encoding utilities
4083
4155
  const { bytesToNumberBE: b2n$1, hexToBytes: h2b$1 } = ut$1;
4156
+ /**
4157
+ * ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
4158
+ *
4159
+ * [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]
4160
+ *
4161
+ * Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
4162
+ */
4084
4163
  const DER$1 = {
4085
4164
  // asn.1 DER encoding utils
4086
4165
  Err: class DERErr extends Error {
@@ -4088,54 +4167,103 @@ const DER$1 = {
4088
4167
  super(m);
4089
4168
  }
4090
4169
  },
4091
- _parseInt(data) {
4092
- const { Err: E } = DER$1;
4093
- if (data.length < 2 || data[0] !== 0x02)
4094
- throw new E('Invalid signature integer tag');
4095
- const len = data[1];
4096
- const res = data.subarray(2, len + 2);
4097
- if (!len || res.length !== len)
4098
- throw new E('Invalid signature integer: wrong length');
4099
- // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
4100
- // since we always use positive integers here. It must always be empty:
4101
- // - add zero byte if exists
4102
- // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
4103
- if (res[0] & 0b10000000)
4104
- throw new E('Invalid signature integer: negative');
4105
- if (res[0] === 0x00 && !(res[1] & 0b10000000))
4106
- throw new E('Invalid signature integer: unnecessary leading zero');
4107
- return { d: b2n$1(res), l: data.subarray(len + 2) }; // d is data, l is left
4170
+ // Basic building block is TLV (Tag-Length-Value)
4171
+ _tlv: {
4172
+ encode: (tag, data) => {
4173
+ const { Err: E } = DER$1;
4174
+ if (tag < 0 || tag > 256)
4175
+ throw new E('tlv.encode: wrong tag');
4176
+ if (data.length & 1)
4177
+ throw new E('tlv.encode: unpadded data');
4178
+ const dataLen = data.length / 2;
4179
+ const len = numberToHexUnpadded$1(dataLen);
4180
+ if ((len.length / 2) & 128)
4181
+ throw new E('tlv.encode: long form length too big');
4182
+ // length of length with long form flag
4183
+ const lenLen = dataLen > 127 ? numberToHexUnpadded$1((len.length / 2) | 128) : '';
4184
+ return `${numberToHexUnpadded$1(tag)}${lenLen}${len}${data}`;
4185
+ },
4186
+ // v - value, l - left bytes (unparsed)
4187
+ decode(tag, data) {
4188
+ const { Err: E } = DER$1;
4189
+ let pos = 0;
4190
+ if (tag < 0 || tag > 256)
4191
+ throw new E('tlv.encode: wrong tag');
4192
+ if (data.length < 2 || data[pos++] !== tag)
4193
+ throw new E('tlv.decode: wrong tlv');
4194
+ const first = data[pos++];
4195
+ const isLong = !!(first & 128); // First bit of first length byte is flag for short/long form
4196
+ let length = 0;
4197
+ if (!isLong)
4198
+ length = first;
4199
+ else {
4200
+ // Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]
4201
+ const lenLen = first & 127;
4202
+ if (!lenLen)
4203
+ throw new E('tlv.decode(long): indefinite length not supported');
4204
+ if (lenLen > 4)
4205
+ throw new E('tlv.decode(long): byte length is too big'); // this will overflow u32 in js
4206
+ const lengthBytes = data.subarray(pos, pos + lenLen);
4207
+ if (lengthBytes.length !== lenLen)
4208
+ throw new E('tlv.decode: length bytes not complete');
4209
+ if (lengthBytes[0] === 0)
4210
+ throw new E('tlv.decode(long): zero leftmost byte');
4211
+ for (const b of lengthBytes)
4212
+ length = (length << 8) | b;
4213
+ pos += lenLen;
4214
+ if (length < 128)
4215
+ throw new E('tlv.decode(long): not minimal encoding');
4216
+ }
4217
+ const v = data.subarray(pos, pos + length);
4218
+ if (v.length !== length)
4219
+ throw new E('tlv.decode: wrong value length');
4220
+ return { v, l: data.subarray(pos + length) };
4221
+ },
4222
+ },
4223
+ // https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
4224
+ // since we always use positive integers here. It must always be empty:
4225
+ // - add zero byte if exists
4226
+ // - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
4227
+ _int: {
4228
+ encode(num) {
4229
+ const { Err: E } = DER$1;
4230
+ if (num < _0n$6)
4231
+ throw new E('integer: negative integers are not allowed');
4232
+ let hex = numberToHexUnpadded$1(num);
4233
+ // Pad with zero byte if negative flag is present
4234
+ if (Number.parseInt(hex[0], 16) & 0b1000)
4235
+ hex = '00' + hex;
4236
+ if (hex.length & 1)
4237
+ throw new E('unexpected assertion');
4238
+ return hex;
4239
+ },
4240
+ decode(data) {
4241
+ const { Err: E } = DER$1;
4242
+ if (data[0] & 128)
4243
+ throw new E('Invalid signature integer: negative');
4244
+ if (data[0] === 0x00 && !(data[1] & 128))
4245
+ throw new E('Invalid signature integer: unnecessary leading zero');
4246
+ return b2n$1(data);
4247
+ },
4108
4248
  },
4109
4249
  toSig(hex) {
4110
4250
  // parse DER signature
4111
- const { Err: E } = DER$1;
4251
+ const { Err: E, _int: int, _tlv: tlv } = DER$1;
4112
4252
  const data = typeof hex === 'string' ? h2b$1(hex) : hex;
4113
4253
  abytes(data);
4114
- let l = data.length;
4115
- if (l < 2 || data[0] != 0x30)
4116
- throw new E('Invalid signature tag');
4117
- if (data[1] !== l - 2)
4118
- throw new E('Invalid signature: incorrect length');
4119
- const { d: r, l: sBytes } = DER$1._parseInt(data.subarray(2));
4120
- const { d: s, l: rBytesLeft } = DER$1._parseInt(sBytes);
4121
- if (rBytesLeft.length)
4254
+ const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
4255
+ if (seqLeftBytes.length)
4122
4256
  throw new E('Invalid signature: left bytes after parsing');
4123
- return { r, s };
4257
+ const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
4258
+ const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
4259
+ if (sLeftBytes.length)
4260
+ throw new E('Invalid signature: left bytes after parsing');
4261
+ return { r: int.decode(rBytes), s: int.decode(sBytes) };
4124
4262
  },
4125
4263
  hexFromSig(sig) {
4126
- // Add leading zero if first byte has negative bit enabled. More details in '_parseInt'
4127
- const slice = (s) => (Number.parseInt(s[0], 16) & 0b1000 ? '00' + s : s);
4128
- const h = (num) => {
4129
- const hex = num.toString(16);
4130
- return hex.length & 1 ? `0${hex}` : hex;
4131
- };
4132
- const s = slice(h(sig.s));
4133
- const r = slice(h(sig.r));
4134
- const shl = s.length / 2;
4135
- const rhl = r.length / 2;
4136
- const sl = h(shl);
4137
- const rl = h(rhl);
4138
- return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
4264
+ const { _tlv: tlv, _int: int } = DER$1;
4265
+ const seq = `${tlv.encode(0x02, int.encode(sig.r))}${tlv.encode(0x02, int.encode(sig.s))}`;
4266
+ return tlv.encode(0x30, seq);
4139
4267
  },
4140
4268
  };
4141
4269
  // Be friendly to bad ECMAScript parsers by not using bigint literals
@@ -4144,6 +4272,7 @@ const _0n$6 = BigInt(0), _1n$8 = BigInt(1); BigInt(2); const _3n$2 = BigInt(3);
4144
4272
  function weierstrassPoints$1(opts) {
4145
4273
  const CURVE = validatePointOpts$1(opts);
4146
4274
  const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
4275
+ const Fn = Field$1(CURVE.n, CURVE.nBitLength);
4147
4276
  const toBytes = CURVE.toBytes ||
4148
4277
  ((_c, point, _isCompressed) => {
4149
4278
  const a = point.toAffine();
@@ -4317,6 +4446,10 @@ function weierstrassPoints$1(opts) {
4317
4446
  static fromPrivateKey(privateKey) {
4318
4447
  return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
4319
4448
  }
4449
+ // Multiscalar Multiplication
4450
+ static msm(points, scalars) {
4451
+ return pippenger(Point, Fn, points, scalars);
4452
+ }
4320
4453
  // "Private method", don't use it directly
4321
4454
  _setWindowSize(windowSize) {
4322
4455
  wnaf.setWindowSize(this, windowSize);
@@ -7557,7 +7690,7 @@ const VerifiableConstants = Object.freeze({
7557
7690
  PUSH_NOTIFICATION: 'push-notification'
7558
7691
  },
7559
7692
  AUTH: {
7560
- AUTH_BJJ_CREDENTAIL_HASH: '013fd3f623559d850fb5b02ff012d0e2',
7693
+ AUTH_BJJ_CREDENTIAL_HASH: '013fd3f623559d850fb5b02ff012d0e2',
7561
7694
  AUTH_BJJ_CREDENTIAL_SCHEMA_JSON_URL: 'https://schema.iden3.io/core/json/auth.json',
7562
7695
  AUTH_BJJ_CREDENTIAL_SCHEMA_JSONLD_URL: 'https://schema.iden3.io/core/jsonld/auth.jsonld',
7563
7696
  AUTH_BJJ_CREDENTIAL_TYPE: 'AuthBJJCredential',
@@ -7589,7 +7722,7 @@ var CredentialStatusType;
7589
7722
  CredentialStatusType["Iden3ReverseSparseMerkleTreeProof"] = "Iden3ReverseSparseMerkleTreeProof";
7590
7723
  // Iden3commRevocationStatusV1 is CredentialStatusType for iden3comm revocation status
7591
7724
  CredentialStatusType["Iden3commRevocationStatusV1"] = "Iden3commRevocationStatusV1.0";
7592
- // Iden3OnсhainSparseMerkleTreeProof2023 is a proof type for MTP proofs with iden3 metadata from blockchain
7725
+ // Iden3OnchainSparseMerkleTreeProof2023 is a proof type for MTP proofs with iden3 metadata from blockchain
7593
7726
  CredentialStatusType["Iden3OnchainSparseMerkleTreeProof2023"] = "Iden3OnchainSparseMerkleTreeProof2023";
7594
7727
  })(CredentialStatusType || (CredentialStatusType = {}));
7595
7728
  /**
@@ -20007,7 +20140,7 @@ class W3CCredential {
20007
20140
  }
20008
20141
  async verifyIden3SparseMerkleTreeProof(proof, coreClaim, resolverURL) {
20009
20142
  await validateDIDDocumentAuth(proof.issuerData.id, resolverURL, proof.issuerData.state.value);
20010
- // root from proof == issuerData.state.сlaimsTreeRoot
20143
+ // root from proof == issuerData.state.claimsTreeRoot
20011
20144
  const { hi, hv } = coreClaim.hiHv();
20012
20145
  const rootFromProofValue = await rootFromProof(proof.mtp, hi, hv);
20013
20146
  if (!rootFromProofValue.equals(proof.issuerData.state.claimsTreeRoot)) {
@@ -53858,7 +53991,7 @@ class OnChainRevocationStorage {
53858
53991
  *
53859
53992
  * Creates an instance of OnChainIssuer.
53860
53993
  * @public
53861
- * @param {string} - onhcain contract address
53994
+ * @param {string} - onchain contract address
53862
53995
  * @param {string} - rpc url to connect to the blockchain
53863
53996
  */
53864
53997
  constructor(_config, contractAddress, _signer) {
@@ -54989,7 +55122,7 @@ class OnChainResolver {
54989
55122
  }
54990
55123
  return network;
54991
55124
  }
54992
- // TODO (illia-korotia): is dirty hack for mock in tests.
55125
+ // TODO: is dirty hack for mock in tests.
54993
55126
  // need to pass to constructor list of state stores not list of network configs
54994
55127
  _getStateStorageForIssuer(issuerId) {
54995
55128
  const issuerChainId = getChainId(DID.blockchainFromId(issuerId), DID.networkIdFromId(issuerId));
@@ -56383,10 +56516,10 @@ function fnvHash(str) {
56383
56516
  hash *= BigInt(0x100000001b3);
56384
56517
  hash %= uint64_max;
56385
56518
  }
56386
- let shash = hash.toString(16);
56387
- const n = 16 - shash.length;
56388
- shash = '0'.repeat(n).concat(shash);
56389
- return shash;
56519
+ let hashHex = hash.toString(16);
56520
+ const n = 16 - hashHex.length;
56521
+ hashHex = '0'.repeat(n).concat(hashHex);
56522
+ return hashHex;
56390
56523
  }
56391
56524
 
56392
56525
  /**