@solana/web3.js 1.95.2 → 1.95.3

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/lib/index.iife.js CHANGED
@@ -2853,6 +2853,10 @@ var solanaWeb3 = (function (exports) {
2853
2853
  if (!isBytes(item))
2854
2854
  throw new Error('Uint8Array expected');
2855
2855
  }
2856
+ function abool(title, value) {
2857
+ if (typeof value !== 'boolean')
2858
+ throw new Error(`${title} must be valid boolean, got "${value}".`);
2859
+ }
2856
2860
  // Array where index 0xf0 (240) is mapped to string 'f0'
2857
2861
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
2858
2862
  /**
@@ -2995,6 +2999,25 @@ var solanaWeb3 = (function (exports) {
2995
2999
  throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
2996
3000
  return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
2997
3001
  }
3002
+ // Is positive bigint
3003
+ const isPosBig = (n) => typeof n === 'bigint' && _0n$5 <= n;
3004
+ function inRange$1(n, min, max) {
3005
+ return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
3006
+ }
3007
+ /**
3008
+ * Asserts min <= n < max. NOTE: It's < max and not <= max.
3009
+ * @example
3010
+ * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)
3011
+ */
3012
+ function aInRange(title, n, min, max) {
3013
+ // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?
3014
+ // consider P=256n, min=0n, max=P
3015
+ // - a for min=0 would require -1: `inRange('x', x, -1n, P)`
3016
+ // - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
3017
+ // - our way is the cleanest: `inRange('x', x, 0n, P)
3018
+ if (!inRange$1(n, min, max))
3019
+ throw new Error(`expected valid ${title}: ${min} <= n < ${max}, got ${typeof n} ${n}`);
3020
+ }
2998
3021
  // Bit operations
2999
3022
  /**
3000
3023
  * Calculates amount of bits in a bigint.
@@ -3125,9 +3148,32 @@ var solanaWeb3 = (function (exports) {
3125
3148
  // const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
3126
3149
  // const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
3127
3150
  // const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
3151
+ /**
3152
+ * throws not implemented error
3153
+ */
3154
+ const notImplemented = () => {
3155
+ throw new Error('not implemented');
3156
+ };
3157
+ /**
3158
+ * Memoizes (caches) computation result.
3159
+ * Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
3160
+ */
3161
+ function memoized(fn) {
3162
+ const map = new WeakMap();
3163
+ return (arg, ...args) => {
3164
+ const val = map.get(arg);
3165
+ if (val !== undefined)
3166
+ return val;
3167
+ const computed = fn(arg, ...args);
3168
+ map.set(arg, computed);
3169
+ return computed;
3170
+ };
3171
+ }
3128
3172
 
3129
3173
  var ut = /*#__PURE__*/Object.freeze({
3130
3174
  __proto__: null,
3175
+ aInRange: aInRange,
3176
+ abool: abool,
3131
3177
  abytes: abytes,
3132
3178
  bitGet: bitGet,
3133
3179
  bitLen: bitLen,
@@ -3142,7 +3188,10 @@ var solanaWeb3 = (function (exports) {
3142
3188
  equalBytes: equalBytes,
3143
3189
  hexToBytes: hexToBytes,
3144
3190
  hexToNumber: hexToNumber,
3191
+ inRange: inRange$1,
3145
3192
  isBytes: isBytes,
3193
+ memoized: memoized,
3194
+ notImplemented: notImplemented,
3146
3195
  numberToBytesBE: numberToBytesBE,
3147
3196
  numberToBytesLE: numberToBytesLE,
3148
3197
  numberToHexUnpadded: numberToHexUnpadded,
@@ -3401,6 +3450,9 @@ var solanaWeb3 = (function (exports) {
3401
3450
  * * a) denormalized operations like mulN instead of mul
3402
3451
  * * b) same object shape: never add or remove keys
3403
3452
  * * c) Object.freeze
3453
+ * NOTE: operations don't check 'isValid' for all elements for performance reasons,
3454
+ * it is caller responsibility to check this.
3455
+ * This is low-level code, please make sure you know what you doing.
3404
3456
  * @param ORDER prime positive bigint
3405
3457
  * @param bitLen how many bits the field consumes
3406
3458
  * @param isLE (def: false) if encoding / decoding should be in little-endian
@@ -3509,6 +3561,10 @@ var solanaWeb3 = (function (exports) {
3509
3561
  // Abelian group utilities
3510
3562
  const _0n$3 = BigInt(0);
3511
3563
  const _1n$5 = BigInt(1);
3564
+ // Since points in different groups cannot be equal (different object constructor),
3565
+ // we can have single place to store precomputes
3566
+ const pointPrecomputes = new WeakMap();
3567
+ const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
3512
3568
  // Elliptic curve multiplication of Point by scalar. Fragile.
3513
3569
  // Scalars should always be less than curve order: this should be checked inside of a curve itself.
3514
3570
  // Creates precomputation tables for fast multiplication:
@@ -3525,7 +3581,12 @@ var solanaWeb3 = (function (exports) {
3525
3581
  const neg = item.negate();
3526
3582
  return condition ? neg : item;
3527
3583
  };
3584
+ const validateW = (W) => {
3585
+ if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
3586
+ throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
3587
+ };
3528
3588
  const opts = (W) => {
3589
+ validateW(W);
3529
3590
  const windows = Math.ceil(bits / W) + 1; // +1, because
3530
3591
  const windowSize = 2 ** (W - 1); // -1 because we skip zero
3531
3592
  return { windows, windowSize };
@@ -3625,19 +3686,25 @@ var solanaWeb3 = (function (exports) {
3625
3686
  // which makes it less const-time: around 1 bigint multiply.
3626
3687
  return { p, f };
3627
3688
  },
3628
- wNAFCached(P, precomputesMap, n, transform) {
3629
- // @ts-ignore
3630
- const W = P._WINDOW_SIZE || 1;
3689
+ wNAFCached(P, n, transform) {
3690
+ const W = pointWindowSizes.get(P) || 1;
3631
3691
  // Calculate precomputes on a first run, reuse them after
3632
- let comp = precomputesMap.get(P);
3692
+ let comp = pointPrecomputes.get(P);
3633
3693
  if (!comp) {
3634
3694
  comp = this.precomputeWindow(P, W);
3635
- if (W !== 1) {
3636
- precomputesMap.set(P, transform(comp));
3637
- }
3695
+ if (W !== 1)
3696
+ pointPrecomputes.set(P, transform(comp));
3638
3697
  }
3639
3698
  return this.wNAF(W, comp, n);
3640
3699
  },
3700
+ // We calculate precomputes for elliptic curve point multiplication
3701
+ // using windowed method. This specifies window size and
3702
+ // stores precomputed values. Usually only base point would be precomputed.
3703
+ setWindowSize(P, W) {
3704
+ validateW(W);
3705
+ pointWindowSizes.set(P, W);
3706
+ pointPrecomputes.delete(P);
3707
+ },
3641
3708
  };
3642
3709
  }
3643
3710
  function validateBasic(curve) {
@@ -3682,7 +3749,13 @@ var solanaWeb3 = (function (exports) {
3682
3749
  // Set defaults
3683
3750
  return Object.freeze({ ...opts });
3684
3751
  }
3685
- // It is not generic twisted curve for now, but ed25519/ed448 generic implementation
3752
+ /**
3753
+ * Creates Twisted Edwards curve with EdDSA signatures.
3754
+ * @example
3755
+ * import { Field } from '@noble/curves/abstract/modular';
3756
+ * // Before that, define BigInt-s: a, d, p, n, Gx, Gy, h
3757
+ * const curve = twistedEdwards({ a, d, Fp: Field(p), n, Gx, Gy, h })
3758
+ */
3686
3759
  function twistedEdwards(curveDef) {
3687
3760
  const CURVE = validateOpts$1(curveDef);
3688
3761
  const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
@@ -3701,28 +3774,59 @@ var solanaWeb3 = (function (exports) {
3701
3774
  const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes); // NOOP
3702
3775
  const domain = CURVE.domain ||
3703
3776
  ((data, ctx, phflag) => {
3777
+ abool('phflag', phflag);
3704
3778
  if (ctx.length || phflag)
3705
3779
  throw new Error('Contexts/pre-hash are not supported');
3706
3780
  return data;
3707
3781
  }); // NOOP
3708
- const inBig = (n) => typeof n === 'bigint' && _0n$2 < n; // n in [1..]
3709
- const inRange = (n, max) => inBig(n) && inBig(max) && n < max; // n in [1..max-1]
3710
- const in0MaskRange = (n) => n === _0n$2 || inRange(n, MASK); // n in [0..MASK-1]
3711
- function assertInRange(n, max) {
3712
- // n in [1..max-1]
3713
- if (inRange(n, max))
3714
- return n;
3715
- throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
3716
- }
3717
- function assertGE0(n) {
3718
- // n in [0..CURVE_ORDER-1]
3719
- return n === _0n$2 ? n : assertInRange(n, CURVE_ORDER); // GE = prime subgroup, not full group
3720
- }
3721
- const pointPrecomputes = new Map();
3722
- function isPoint(other) {
3782
+ // 0 <= n < MASK
3783
+ // Coordinates larger than Fp.ORDER are allowed for zip215
3784
+ function aCoordinate(title, n) {
3785
+ aInRange('coordinate ' + title, n, _0n$2, MASK);
3786
+ }
3787
+ function assertPoint(other) {
3723
3788
  if (!(other instanceof Point))
3724
3789
  throw new Error('ExtendedPoint expected');
3725
3790
  }
3791
+ // Converts Extended point to default (x, y) coordinates.
3792
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
3793
+ const toAffineMemo = memoized((p, iz) => {
3794
+ const { ex: x, ey: y, ez: z } = p;
3795
+ const is0 = p.is0();
3796
+ if (iz == null)
3797
+ iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
3798
+ const ax = modP(x * iz);
3799
+ const ay = modP(y * iz);
3800
+ const zz = modP(z * iz);
3801
+ if (is0)
3802
+ return { x: _0n$2, y: _1n$4 };
3803
+ if (zz !== _1n$4)
3804
+ throw new Error('invZ was invalid');
3805
+ return { x: ax, y: ay };
3806
+ });
3807
+ const assertValidMemo = memoized((p) => {
3808
+ const { a, d } = CURVE;
3809
+ if (p.is0())
3810
+ throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
3811
+ // Equation in affine coordinates: ax² + y² = 1 + dx²y²
3812
+ // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
3813
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
3814
+ const X2 = modP(X * X); // X²
3815
+ const Y2 = modP(Y * Y); // Y²
3816
+ const Z2 = modP(Z * Z); // Z²
3817
+ const Z4 = modP(Z2 * Z2); // Z⁴
3818
+ const aX2 = modP(X2 * a); // aX²
3819
+ const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
3820
+ const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
3821
+ if (left !== right)
3822
+ throw new Error('bad point: equation left != right (1)');
3823
+ // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
3824
+ const XY = modP(X * Y);
3825
+ const ZT = modP(Z * T);
3826
+ if (XY !== ZT)
3827
+ throw new Error('bad point: equation left != right (2)');
3828
+ return true;
3829
+ });
3726
3830
  // Extended Point works in extended coordinates: (x, y, z, t) ∋ (x=x/z, y=y/z, t=xy).
3727
3831
  // https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
3728
3832
  class Point {
@@ -3731,14 +3835,11 @@ var solanaWeb3 = (function (exports) {
3731
3835
  this.ey = ey;
3732
3836
  this.ez = ez;
3733
3837
  this.et = et;
3734
- if (!in0MaskRange(ex))
3735
- throw new Error('x required');
3736
- if (!in0MaskRange(ey))
3737
- throw new Error('y required');
3738
- if (!in0MaskRange(ez))
3739
- throw new Error('z required');
3740
- if (!in0MaskRange(et))
3741
- throw new Error('t required');
3838
+ aCoordinate('x', ex);
3839
+ aCoordinate('y', ey);
3840
+ aCoordinate('z', ez);
3841
+ aCoordinate('t', et);
3842
+ Object.freeze(this);
3742
3843
  }
3743
3844
  get x() {
3744
3845
  return this.toAffine().x;
@@ -3750,8 +3851,8 @@ var solanaWeb3 = (function (exports) {
3750
3851
  if (p instanceof Point)
3751
3852
  throw new Error('extended point not allowed');
3752
3853
  const { x, y } = p || {};
3753
- if (!in0MaskRange(x) || !in0MaskRange(y))
3754
- throw new Error('invalid affine point');
3854
+ aCoordinate('x', x);
3855
+ aCoordinate('y', y);
3755
3856
  return new Point(x, y, _1n$4, modP(x * y));
3756
3857
  }
3757
3858
  static normalizeZ(points) {
@@ -3760,36 +3861,16 @@ var solanaWeb3 = (function (exports) {
3760
3861
  }
3761
3862
  // "Private method", don't use it directly
3762
3863
  _setWindowSize(windowSize) {
3763
- this._WINDOW_SIZE = windowSize;
3764
- pointPrecomputes.delete(this);
3864
+ wnaf.setWindowSize(this, windowSize);
3765
3865
  }
3766
3866
  // Not required for fromHex(), which always creates valid points.
3767
3867
  // Could be useful for fromAffine().
3768
3868
  assertValidity() {
3769
- const { a, d } = CURVE;
3770
- if (this.is0())
3771
- throw new Error('bad point: ZERO'); // TODO: optimize, with vars below?
3772
- // Equation in affine coordinates: ax² + y² = 1 + dx²y²
3773
- // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
3774
- const { ex: X, ey: Y, ez: Z, et: T } = this;
3775
- const X2 = modP(X * X); // X²
3776
- const Y2 = modP(Y * Y); // Y²
3777
- const Z2 = modP(Z * Z); // Z²
3778
- const Z4 = modP(Z2 * Z2); // Z⁴
3779
- const aX2 = modP(X2 * a); // aX²
3780
- const left = modP(Z2 * modP(aX2 + Y2)); // (aX² + Y²)Z²
3781
- const right = modP(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
3782
- if (left !== right)
3783
- throw new Error('bad point: equation left != right (1)');
3784
- // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
3785
- const XY = modP(X * Y);
3786
- const ZT = modP(Z * T);
3787
- if (XY !== ZT)
3788
- throw new Error('bad point: equation left != right (2)');
3869
+ assertValidMemo(this);
3789
3870
  }
3790
3871
  // Compare one point to another.
3791
3872
  equals(other) {
3792
- isPoint(other);
3873
+ assertPoint(other);
3793
3874
  const { ex: X1, ey: Y1, ez: Z1 } = this;
3794
3875
  const { ex: X2, ey: Y2, ez: Z2 } = other;
3795
3876
  const X1Z2 = modP(X1 * Z2);
@@ -3830,7 +3911,7 @@ var solanaWeb3 = (function (exports) {
3830
3911
  // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
3831
3912
  // Cost: 9M + 1*a + 1*d + 7add.
3832
3913
  add(other) {
3833
- isPoint(other);
3914
+ assertPoint(other);
3834
3915
  const { a, d } = CURVE;
3835
3916
  const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
3836
3917
  const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
@@ -3873,11 +3954,13 @@ var solanaWeb3 = (function (exports) {
3873
3954
  return this.add(other.negate());
3874
3955
  }
3875
3956
  wNAF(n) {
3876
- return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
3957
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
3877
3958
  }
3878
3959
  // Constant-time multiplication.
3879
3960
  multiply(scalar) {
3880
- const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
3961
+ const n = scalar;
3962
+ aInRange('scalar', n, _1n$4, CURVE_ORDER); // 1 <= scalar < L
3963
+ const { p, f } = this.wNAF(n);
3881
3964
  return Point.normalizeZ([p, f])[0];
3882
3965
  }
3883
3966
  // Non-constant-time multiplication. Uses double-and-add algorithm.
@@ -3885,7 +3968,8 @@ var solanaWeb3 = (function (exports) {
3885
3968
  // an exposed private key e.g. sig verification.
3886
3969
  // Does NOT allow scalars higher than CURVE.n.
3887
3970
  multiplyUnsafe(scalar) {
3888
- let n = assertGE0(scalar); // 0 <= scalar < CURVE.n
3971
+ const n = scalar;
3972
+ aInRange('scalar', n, _0n$2, CURVE_ORDER); // 0 <= scalar < L
3889
3973
  if (n === _0n$2)
3890
3974
  return I;
3891
3975
  if (this.equals(I) || n === _1n$4)
@@ -3909,18 +3993,7 @@ var solanaWeb3 = (function (exports) {
3909
3993
  // Converts Extended point to default (x, y) coordinates.
3910
3994
  // Can accept precomputed Z^-1 - for example, from invertBatch.
3911
3995
  toAffine(iz) {
3912
- const { ex: x, ey: y, ez: z } = this;
3913
- const is0 = this.is0();
3914
- if (iz == null)
3915
- iz = is0 ? _8n$1 : Fp.inv(z); // 8 was chosen arbitrarily
3916
- const ax = modP(x * iz);
3917
- const ay = modP(y * iz);
3918
- const zz = modP(z * iz);
3919
- if (is0)
3920
- return { x: _0n$2, y: _1n$4 };
3921
- if (zz !== _1n$4)
3922
- throw new Error('invZ was invalid');
3923
- return { x: ax, y: ay };
3996
+ return toAffineMemo(this, iz);
3924
3997
  }
3925
3998
  clearCofactor() {
3926
3999
  const { h: cofactor } = CURVE;
@@ -3934,18 +4007,16 @@ var solanaWeb3 = (function (exports) {
3934
4007
  const { d, a } = CURVE;
3935
4008
  const len = Fp.BYTES;
3936
4009
  hex = ensureBytes('pointHex', hex, len); // copy hex to a new array
4010
+ abool('zip215', zip215);
3937
4011
  const normed = hex.slice(); // copy again, we'll manipulate it
3938
4012
  const lastByte = hex[len - 1]; // select last byte
3939
4013
  normed[len - 1] = lastByte & ~0x80; // clear last bit
3940
4014
  const y = bytesToNumberLE(normed);
3941
- if (y === _0n$2) ;
3942
- else {
3943
- // RFC8032 prohibits >= p, but ZIP215 doesn't
3944
- if (zip215)
3945
- assertInRange(y, MASK); // zip215=true [1..P-1] (2^255-19-1 for ed25519)
3946
- else
3947
- assertInRange(y, Fp.ORDER); // zip215=false [1..MASK-1] (2^256-1 for ed25519)
3948
- }
4015
+ // RFC8032 prohibits >= p, but ZIP215 doesn't
4016
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
4017
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
4018
+ const max = zip215 ? MASK : Fp.ORDER;
4019
+ aInRange('pointHex.y', y, _0n$2, max);
3949
4020
  // Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
3950
4021
  // ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
3951
4022
  const y2 = modP(y * y); // denominator is always non-0 mod p.
@@ -4020,7 +4091,7 @@ var solanaWeb3 = (function (exports) {
4020
4091
  const R = G.multiply(r).toRawBytes(); // R = rG
4021
4092
  const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
4022
4093
  const s = modN(r + k * scalar); // S = (r + k * s) mod L
4023
- assertGE0(s); // 0 <= s < l
4094
+ aInRange('signature.s', s, _0n$2, CURVE_ORDER); // 0 <= s < l
4024
4095
  const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
4025
4096
  return ensureBytes('result', res, nByteLength * 2); // 64-byte signature
4026
4097
  }
@@ -4030,6 +4101,8 @@ var solanaWeb3 = (function (exports) {
4030
4101
  const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
4031
4102
  sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
4032
4103
  msg = ensureBytes('message', msg);
4104
+ if (zip215 !== undefined)
4105
+ abool('zip215', zip215);
4033
4106
  if (prehash)
4034
4107
  msg = prehash(msg); // for ed25519ph, etc
4035
4108
  const s = bytesToNumberLE(sig.slice(len, 2 * len));
@@ -4168,6 +4241,9 @@ var solanaWeb3 = (function (exports) {
4168
4241
  // Constant-time, u/√v
4169
4242
  uvRatio,
4170
4243
  }))();
4244
+ /**
4245
+ * ed25519 curve with EdDSA signatures.
4246
+ */
4171
4247
  const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
4172
4248
 
4173
4249
  /**
@@ -14191,7 +14267,7 @@ var solanaWeb3 = (function (exports) {
14191
14267
  isSigner: false,
14192
14268
  isWritable: true
14193
14269
  }];
14194
- if (params.basePubkey != params.fromPubkey) {
14270
+ if (!params.basePubkey.equals(params.fromPubkey)) {
14195
14271
  keys.push({
14196
14272
  pubkey: params.basePubkey,
14197
14273
  isSigner: true,
@@ -18538,7 +18614,7 @@ var solanaWeb3 = (function (exports) {
18538
18614
 
18539
18615
  /** @internal */
18540
18616
  const COMMON_HTTP_HEADERS = {
18541
- 'solana-client': `js/${"0.0.0-development"}`
18617
+ 'solana-client': `js/${"1.0.0-maintenance"}`
18542
18618
  };
18543
18619
 
18544
18620
  /**
@@ -22399,6 +22475,12 @@ var solanaWeb3 = (function (exports) {
22399
22475
 
22400
22476
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
22401
22477
  // Short Weierstrass curve. The formula is: y² = x³ + ax + b
22478
+ function validateSigVerOpts(opts) {
22479
+ if (opts.lowS !== undefined)
22480
+ abool('lowS', opts.lowS);
22481
+ if (opts.prehash !== undefined)
22482
+ abool('prehash', opts.prehash);
22483
+ }
22402
22484
  function validatePointOpts(curve) {
22403
22485
  const opts = validateBasic(curve);
22404
22486
  validateObject(opts, {
@@ -22523,16 +22605,12 @@ var solanaWeb3 = (function (exports) {
22523
22605
  throw new Error('bad generator point: equation left != right');
22524
22606
  // Valid group elements reside in range 1..n-1
22525
22607
  function isWithinCurveOrder(num) {
22526
- return typeof num === 'bigint' && _0n < num && num < CURVE.n;
22527
- }
22528
- function assertGE(num) {
22529
- if (!isWithinCurveOrder(num))
22530
- throw new Error('Expected valid bigint: 0 < bigint < curve.n');
22608
+ return inRange$1(num, _1n$1, CURVE.n);
22531
22609
  }
22532
22610
  // Validates if priv key is valid and converts it to bigint.
22533
22611
  // Supports options allowedPrivateKeyLengths and wrapPrivateKey.
22534
22612
  function normPrivateKeyToScalar(key) {
22535
- const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
22613
+ const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n: N } = CURVE;
22536
22614
  if (lengths && typeof key !== 'bigint') {
22537
22615
  if (isBytes(key))
22538
22616
  key = bytesToHex(key);
@@ -22552,15 +22630,61 @@ var solanaWeb3 = (function (exports) {
22552
22630
  throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
22553
22631
  }
22554
22632
  if (wrapPrivateKey)
22555
- num = mod(num, n); // disabled by default, enabled for BLS
22556
- assertGE(num); // num in range [1..N-1]
22633
+ num = mod(num, N); // disabled by default, enabled for BLS
22634
+ aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
22557
22635
  return num;
22558
22636
  }
22559
- const pointPrecomputes = new Map();
22560
22637
  function assertPrjPoint(other) {
22561
22638
  if (!(other instanceof Point))
22562
22639
  throw new Error('ProjectivePoint expected');
22563
22640
  }
22641
+ // Memoized toAffine / validity check. They are heavy. Points are immutable.
22642
+ // Converts Projective point to affine (x, y) coordinates.
22643
+ // Can accept precomputed Z^-1 - for example, from invertBatch.
22644
+ // (x, y, z) ∋ (x=x/z, y=y/z)
22645
+ const toAffineMemo = memoized((p, iz) => {
22646
+ const { px: x, py: y, pz: z } = p;
22647
+ // Fast-path for normalized points
22648
+ if (Fp.eql(z, Fp.ONE))
22649
+ return { x, y };
22650
+ const is0 = p.is0();
22651
+ // If invZ was 0, we return zero point. However we still want to execute
22652
+ // all operations, so we replace invZ with a random number, 1.
22653
+ if (iz == null)
22654
+ iz = is0 ? Fp.ONE : Fp.inv(z);
22655
+ const ax = Fp.mul(x, iz);
22656
+ const ay = Fp.mul(y, iz);
22657
+ const zz = Fp.mul(z, iz);
22658
+ if (is0)
22659
+ return { x: Fp.ZERO, y: Fp.ZERO };
22660
+ if (!Fp.eql(zz, Fp.ONE))
22661
+ throw new Error('invZ was invalid');
22662
+ return { x: ax, y: ay };
22663
+ });
22664
+ // NOTE: on exception this will crash 'cached' and no value will be set.
22665
+ // Otherwise true will be return
22666
+ const assertValidMemo = memoized((p) => {
22667
+ if (p.is0()) {
22668
+ // (0, 1, 0) aka ZERO is invalid in most contexts.
22669
+ // In BLS, ZERO can be serialized, so we allow it.
22670
+ // (0, 0, 0) is wrong representation of ZERO and is always invalid.
22671
+ if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
22672
+ return;
22673
+ throw new Error('bad point: ZERO');
22674
+ }
22675
+ // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
22676
+ const { x, y } = p.toAffine();
22677
+ // Check if x, y are valid field elements
22678
+ if (!Fp.isValid(x) || !Fp.isValid(y))
22679
+ throw new Error('bad point: x or y not FE');
22680
+ const left = Fp.sqr(y); // y²
22681
+ const right = weierstrassEquation(x); // x³ + ax + b
22682
+ if (!Fp.eql(left, right))
22683
+ throw new Error('bad point: equation left != right');
22684
+ if (!p.isTorsionFree())
22685
+ throw new Error('bad point: not in prime-order subgroup');
22686
+ return true;
22687
+ });
22564
22688
  /**
22565
22689
  * Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
22566
22690
  * Default Point works in 2d / affine coordinates: (x, y)
@@ -22577,6 +22701,7 @@ var solanaWeb3 = (function (exports) {
22577
22701
  throw new Error('y required');
22578
22702
  if (pz == null || !Fp.isValid(pz))
22579
22703
  throw new Error('z required');
22704
+ Object.freeze(this);
22580
22705
  }
22581
22706
  // Does not validate if the point is on-curve.
22582
22707
  // Use fromHex instead, or call assertValidity() later.
@@ -22623,30 +22748,11 @@ var solanaWeb3 = (function (exports) {
22623
22748
  }
22624
22749
  // "Private method", don't use it directly
22625
22750
  _setWindowSize(windowSize) {
22626
- this._WINDOW_SIZE = windowSize;
22627
- pointPrecomputes.delete(this);
22751
+ wnaf.setWindowSize(this, windowSize);
22628
22752
  }
22629
22753
  // A point on curve is valid if it conforms to equation.
22630
22754
  assertValidity() {
22631
- if (this.is0()) {
22632
- // (0, 1, 0) aka ZERO is invalid in most contexts.
22633
- // In BLS, ZERO can be serialized, so we allow it.
22634
- // (0, 0, 0) is wrong representation of ZERO and is always invalid.
22635
- if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
22636
- return;
22637
- throw new Error('bad point: ZERO');
22638
- }
22639
- // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
22640
- const { x, y } = this.toAffine();
22641
- // Check if x, y are valid field elements
22642
- if (!Fp.isValid(x) || !Fp.isValid(y))
22643
- throw new Error('bad point: x or y not FE');
22644
- const left = Fp.sqr(y); // y²
22645
- const right = weierstrassEquation(x); // x³ + ax + b
22646
- if (!Fp.eql(left, right))
22647
- throw new Error('bad point: equation left != right');
22648
- if (!this.isTorsionFree())
22649
- throw new Error('bad point: not in prime-order subgroup');
22755
+ assertValidMemo(this);
22650
22756
  }
22651
22757
  hasEvenY() {
22652
22758
  const { y } = this.toAffine();
@@ -22773,28 +22879,25 @@ var solanaWeb3 = (function (exports) {
22773
22879
  return this.equals(Point.ZERO);
22774
22880
  }
22775
22881
  wNAF(n) {
22776
- return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
22777
- const toInv = Fp.invertBatch(comp.map((p) => p.pz));
22778
- return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
22779
- });
22882
+ return wnaf.wNAFCached(this, n, Point.normalizeZ);
22780
22883
  }
22781
22884
  /**
22782
22885
  * Non-constant-time multiplication. Uses double-and-add algorithm.
22783
22886
  * It's faster, but should only be used when you don't care about
22784
22887
  * an exposed private key e.g. sig verification, which works over *public* keys.
22785
22888
  */
22786
- multiplyUnsafe(n) {
22889
+ multiplyUnsafe(sc) {
22890
+ aInRange('scalar', sc, _0n, CURVE.n);
22787
22891
  const I = Point.ZERO;
22788
- if (n === _0n)
22892
+ if (sc === _0n)
22789
22893
  return I;
22790
- assertGE(n); // Will throw on 0
22791
- if (n === _1n$1)
22894
+ if (sc === _1n$1)
22792
22895
  return this;
22793
22896
  const { endo } = CURVE;
22794
22897
  if (!endo)
22795
- return wnaf.unsafeLadder(this, n);
22898
+ return wnaf.unsafeLadder(this, sc);
22796
22899
  // Apply endomorphism
22797
- let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
22900
+ let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
22798
22901
  let k1p = I;
22799
22902
  let k2p = I;
22800
22903
  let d = this;
@@ -22824,12 +22927,11 @@ var solanaWeb3 = (function (exports) {
22824
22927
  * @returns New point
22825
22928
  */
22826
22929
  multiply(scalar) {
22827
- assertGE(scalar);
22828
- let n = scalar;
22930
+ const { endo, n: N } = CURVE;
22931
+ aInRange('scalar', scalar, _1n$1, N);
22829
22932
  let point, fake; // Fake point is used to const-time mult
22830
- const { endo } = CURVE;
22831
22933
  if (endo) {
22832
- const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
22934
+ const { k1neg, k1, k2neg, k2 } = endo.splitScalar(scalar);
22833
22935
  let { p: k1p, f: f1p } = this.wNAF(k1);
22834
22936
  let { p: k2p, f: f2p } = this.wNAF(k2);
22835
22937
  k1p = wnaf.constTimeNegate(k1neg, k1p);
@@ -22839,7 +22941,7 @@ var solanaWeb3 = (function (exports) {
22839
22941
  fake = f1p.add(f2p);
22840
22942
  }
22841
22943
  else {
22842
- const { p, f } = this.wNAF(n);
22944
+ const { p, f } = this.wNAF(scalar);
22843
22945
  point = p;
22844
22946
  fake = f;
22845
22947
  }
@@ -22863,20 +22965,7 @@ var solanaWeb3 = (function (exports) {
22863
22965
  // Can accept precomputed Z^-1 - for example, from invertBatch.
22864
22966
  // (x, y, z) ∋ (x=x/z, y=y/z)
22865
22967
  toAffine(iz) {
22866
- const { px: x, py: y, pz: z } = this;
22867
- const is0 = this.is0();
22868
- // If invZ was 0, we return zero point. However we still want to execute
22869
- // all operations, so we replace invZ with a random number, 1.
22870
- if (iz == null)
22871
- iz = is0 ? Fp.ONE : Fp.inv(z);
22872
- const ax = Fp.mul(x, iz);
22873
- const ay = Fp.mul(y, iz);
22874
- const zz = Fp.mul(z, iz);
22875
- if (is0)
22876
- return { x: Fp.ZERO, y: Fp.ZERO };
22877
- if (!Fp.eql(zz, Fp.ONE))
22878
- throw new Error('invZ was invalid');
22879
- return { x: ax, y: ay };
22968
+ return toAffineMemo(this, iz);
22880
22969
  }
22881
22970
  isTorsionFree() {
22882
22971
  const { h: cofactor, isTorsionFree } = CURVE;
@@ -22895,10 +22984,12 @@ var solanaWeb3 = (function (exports) {
22895
22984
  return this.multiplyUnsafe(CURVE.h);
22896
22985
  }
22897
22986
  toRawBytes(isCompressed = true) {
22987
+ abool('isCompressed', isCompressed);
22898
22988
  this.assertValidity();
22899
22989
  return toBytes(Point, this, isCompressed);
22900
22990
  }
22901
22991
  toHex(isCompressed = true) {
22992
+ abool('isCompressed', isCompressed);
22902
22993
  return bytesToHex(this.toRawBytes(isCompressed));
22903
22994
  }
22904
22995
  }
@@ -22928,14 +23019,18 @@ var solanaWeb3 = (function (exports) {
22928
23019
  });
22929
23020
  return Object.freeze({ lowS: true, ...opts });
22930
23021
  }
23022
+ /**
23023
+ * Creates short weierstrass curve and ECDSA signature methods for it.
23024
+ * @example
23025
+ * import { Field } from '@noble/curves/abstract/modular';
23026
+ * // Before that, define BigInt-s: a, b, p, n, Gx, Gy
23027
+ * const curve = weierstrass({ a, b, Fp: Field(p), n, Gx, Gy, h: 1n })
23028
+ */
22931
23029
  function weierstrass(curveDef) {
22932
23030
  const CURVE = validateOpts(curveDef);
22933
23031
  const { Fp, n: CURVE_ORDER } = CURVE;
22934
23032
  const compressedLen = Fp.BYTES + 1; // e.g. 33 for 32
22935
23033
  const uncompressedLen = 2 * Fp.BYTES + 1; // e.g. 65 for 32
22936
- function isValidFieldElement(num) {
22937
- return _0n < num && num < Fp.ORDER; // 0 is banned since it's not invertible FE
22938
- }
22939
23034
  function modN(a) {
22940
23035
  return mod(a, CURVE_ORDER);
22941
23036
  }
@@ -22948,6 +23043,7 @@ var solanaWeb3 = (function (exports) {
22948
23043
  const a = point.toAffine();
22949
23044
  const x = Fp.toBytes(a.x);
22950
23045
  const cat = concatBytes;
23046
+ abool('isCompressed', isCompressed);
22951
23047
  if (isCompressed) {
22952
23048
  return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
22953
23049
  }
@@ -22962,7 +23058,7 @@ var solanaWeb3 = (function (exports) {
22962
23058
  // this.assertValidity() is done inside of fromHex
22963
23059
  if (len === compressedLen && (head === 0x02 || head === 0x03)) {
22964
23060
  const x = bytesToNumberBE(tail);
22965
- if (!isValidFieldElement(x))
23061
+ if (!inRange$1(x, _1n$1, Fp.ORDER))
22966
23062
  throw new Error('Point is not on curve');
22967
23063
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
22968
23064
  let y;
@@ -23023,11 +23119,8 @@ var solanaWeb3 = (function (exports) {
23023
23119
  return new Signature(r, s);
23024
23120
  }
23025
23121
  assertValidity() {
23026
- // can use assertGE here
23027
- if (!isWithinCurveOrder(this.r))
23028
- throw new Error('r must be 0 < r < CURVE.n');
23029
- if (!isWithinCurveOrder(this.s))
23030
- throw new Error('s must be 0 < s < CURVE.n');
23122
+ aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
23123
+ aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
23031
23124
  }
23032
23125
  addRecoveryBit(recovery) {
23033
23126
  return new Signature(this.r, this.s, recovery);
@@ -23170,10 +23263,7 @@ var solanaWeb3 = (function (exports) {
23170
23263
  * Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
23171
23264
  */
23172
23265
  function int2octets(num) {
23173
- if (typeof num !== 'bigint')
23174
- throw new Error('bigint expected');
23175
- if (!(_0n <= num && num < ORDER_MASK))
23176
- throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
23266
+ aInRange(`num < 2^${CURVE.nBitLength}`, num, _0n, ORDER_MASK);
23177
23267
  // works with order, can have different size than numToField!
23178
23268
  return numberToBytesBE(num, CURVE.nByteLength);
23179
23269
  }
@@ -23190,6 +23280,7 @@ var solanaWeb3 = (function (exports) {
23190
23280
  if (lowS == null)
23191
23281
  lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
23192
23282
  msgHash = ensureBytes('msgHash', msgHash);
23283
+ validateSigVerOpts(opts);
23193
23284
  if (prehash)
23194
23285
  msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
23195
23286
  // We can't later call bits2octets, since nested bits2int is broken for curves
@@ -23276,6 +23367,7 @@ var solanaWeb3 = (function (exports) {
23276
23367
  publicKey = ensureBytes('publicKey', publicKey);
23277
23368
  if ('strict' in opts)
23278
23369
  throw new Error('options.strict was renamed to lowS');
23370
+ validateSigVerOpts(opts);
23279
23371
  const { lowS, prehash } = opts;
23280
23372
  let _sig = undefined;
23281
23373
  let P;
@@ -23382,6 +23474,9 @@ var solanaWeb3 = (function (exports) {
23382
23474
  return root;
23383
23475
  }
23384
23476
  const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
23477
+ /**
23478
+ * secp256k1 short weierstrass curve and ECDSA signatures over it.
23479
+ */
23385
23480
  const secp256k1 = createCurve({
23386
23481
  a: BigInt(0), // equation params: a, b
23387
23482
  b: BigInt(7), // Seem to be rigid: bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975