@noble/curves 1.2.0 → 1.4.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.
Files changed (92) hide show
  1. package/README.md +143 -194
  2. package/abstract/bls.d.ts +29 -12
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +58 -8
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.js.map +1 -1
  7. package/abstract/edwards.js.map +1 -1
  8. package/abstract/hash-to-curve.d.ts +1 -1
  9. package/abstract/hash-to-curve.d.ts.map +1 -1
  10. package/abstract/hash-to-curve.js +10 -21
  11. package/abstract/hash-to-curve.js.map +1 -1
  12. package/abstract/modular.js.map +1 -1
  13. package/abstract/montgomery.d.ts.map +1 -1
  14. package/abstract/montgomery.js +5 -7
  15. package/abstract/montgomery.js.map +1 -1
  16. package/abstract/poseidon.js.map +1 -1
  17. package/abstract/utils.d.ts +4 -2
  18. package/abstract/utils.d.ts.map +1 -1
  19. package/abstract/utils.js +61 -36
  20. package/abstract/utils.js.map +1 -1
  21. package/abstract/weierstrass.d.ts +24 -28
  22. package/abstract/weierstrass.d.ts.map +1 -1
  23. package/abstract/weierstrass.js +13 -7
  24. package/abstract/weierstrass.js.map +1 -1
  25. package/bls12-381.d.ts.map +1 -1
  26. package/bls12-381.js +138 -83
  27. package/bls12-381.js.map +1 -1
  28. package/bn254.d.ts +3 -2
  29. package/bn254.d.ts.map +1 -1
  30. package/bn254.js +3 -2
  31. package/bn254.js.map +1 -1
  32. package/ed25519.d.ts +4 -2
  33. package/ed25519.d.ts.map +1 -1
  34. package/ed25519.js +8 -2
  35. package/ed25519.js.map +1 -1
  36. package/ed448.d.ts +4 -2
  37. package/ed448.d.ts.map +1 -1
  38. package/ed448.js +10 -1
  39. package/ed448.js.map +1 -1
  40. package/esm/abstract/bls.js +58 -8
  41. package/esm/abstract/bls.js.map +1 -1
  42. package/esm/abstract/curve.js.map +1 -1
  43. package/esm/abstract/edwards.js.map +1 -1
  44. package/esm/abstract/hash-to-curve.js +11 -22
  45. package/esm/abstract/hash-to-curve.js.map +1 -1
  46. package/esm/abstract/modular.js.map +1 -1
  47. package/esm/abstract/montgomery.js +5 -7
  48. package/esm/abstract/montgomery.js.map +1 -1
  49. package/esm/abstract/poseidon.js.map +1 -1
  50. package/esm/abstract/utils.js +58 -35
  51. package/esm/abstract/utils.js.map +1 -1
  52. package/esm/abstract/weierstrass.js +13 -7
  53. package/esm/abstract/weierstrass.js.map +1 -1
  54. package/esm/bls12-381.js +139 -84
  55. package/esm/bls12-381.js.map +1 -1
  56. package/esm/bn254.js +3 -2
  57. package/esm/bn254.js.map +1 -1
  58. package/esm/ed25519.js +8 -2
  59. package/esm/ed25519.js.map +1 -1
  60. package/esm/ed448.js +10 -1
  61. package/esm/ed448.js.map +1 -1
  62. package/esm/index.js +1 -1
  63. package/esm/index.js.map +1 -1
  64. package/esm/jubjub.js.map +1 -1
  65. package/esm/p256.js +2 -2
  66. package/esm/p256.js.map +1 -1
  67. package/esm/p384.js +2 -2
  68. package/esm/p384.js.map +1 -1
  69. package/esm/p521.js +3 -3
  70. package/esm/p521.js.map +1 -1
  71. package/esm/secp256k1.js +6 -6
  72. package/esm/secp256k1.js.map +1 -1
  73. package/jubjub.js.map +1 -1
  74. package/p256.js +2 -2
  75. package/p256.js.map +1 -1
  76. package/p384.js +2 -2
  77. package/p384.js.map +1 -1
  78. package/p521.js +3 -3
  79. package/p521.js.map +1 -1
  80. package/package.json +7 -7
  81. package/secp256k1.js +6 -6
  82. package/secp256k1.js.map +1 -1
  83. package/src/abstract/bls.ts +119 -21
  84. package/src/abstract/hash-to-curve.ts +12 -20
  85. package/src/abstract/montgomery.ts +4 -6
  86. package/src/abstract/utils.ts +57 -28
  87. package/src/abstract/weierstrass.ts +25 -10
  88. package/src/bls12-381.ts +128 -70
  89. package/src/bn254.ts +3 -2
  90. package/src/ed25519.ts +10 -2
  91. package/src/ed448.ts +18 -3
  92. package/src/package.json +3 -0
@@ -1,7 +1,8 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  import type { Group, GroupConstructor, AffinePoint } from './curve.js';
3
3
  import { mod, IField } from './modular.js';
4
- import { bytesToNumberBE, CHash, concatBytes, utf8ToBytes, validateObject } from './utils.js';
4
+ import type { CHash } from './utils.js';
5
+ import { bytesToNumberBE, abytes, concatBytes, utf8ToBytes, validateObject } from './utils.js';
5
6
 
6
7
  /**
7
8
  * * `DST` is a domain separation tag, defined in section 2.2.5
@@ -21,12 +22,6 @@ export type Opts = {
21
22
  hash: CHash;
22
23
  };
23
24
 
24
- function validateDST(dst: UnicodeOrBytes): Uint8Array {
25
- if (dst instanceof Uint8Array) return dst;
26
- if (typeof dst === 'string') return utf8ToBytes(dst);
27
- throw new Error('DST must be Uint8Array or string');
28
- }
29
-
30
25
  // Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
31
26
  const os2ip = bytesToNumberBE;
32
27
 
@@ -51,10 +46,7 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
51
46
  return arr;
52
47
  }
53
48
 
54
- function isBytes(item: unknown): void {
55
- if (!(item instanceof Uint8Array)) throw new Error('Uint8Array expected');
56
- }
57
- function isNum(item: unknown): void {
49
+ function anum(item: unknown): void {
58
50
  if (!Number.isSafeInteger(item)) throw new Error('number expected');
59
51
  }
60
52
 
@@ -66,9 +58,9 @@ export function expand_message_xmd(
66
58
  lenInBytes: number,
67
59
  H: CHash
68
60
  ): Uint8Array {
69
- isBytes(msg);
70
- isBytes(DST);
71
- isNum(lenInBytes);
61
+ abytes(msg);
62
+ abytes(DST);
63
+ anum(lenInBytes);
72
64
  // https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
73
65
  if (DST.length > 255) DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
74
66
  const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
@@ -100,9 +92,9 @@ export function expand_message_xof(
100
92
  k: number,
101
93
  H: CHash
102
94
  ): Uint8Array {
103
- isBytes(msg);
104
- isBytes(DST);
105
- isNum(lenInBytes);
95
+ abytes(msg);
96
+ abytes(DST);
97
+ anum(lenInBytes);
106
98
  // https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
107
99
  // DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
108
100
  if (DST.length > 255) {
@@ -139,9 +131,9 @@ export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bi
139
131
  hash: 'hash',
140
132
  });
141
133
  const { p, k, m, hash, expand, DST: _DST } = options;
142
- isBytes(msg);
143
- isNum(count);
144
- const DST = validateDST(_DST);
134
+ abytes(msg);
135
+ anum(count);
136
+ const DST = typeof _DST === 'string' ? utf8ToBytes(_DST) : _DST;
145
137
  const log2p = p.toString(2).length;
146
138
  const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
147
139
  const len_in_bytes = count * m * L;
@@ -150,17 +150,15 @@ export function montgomery(curveDef: CurveType): CurveFn {
150
150
  function decodeUCoordinate(uEnc: Hex): bigint {
151
151
  // Section 5: When receiving such an array, implementations of X25519
152
152
  // MUST mask the most significant bit in the final byte.
153
- // This is very ugly way, but it works because fieldLen-1 is outside of bounds for X448, so this becomes NOOP
154
- // fieldLen - scalaryBytes = 1 for X448 and = 0 for X25519
155
153
  const u = ensureBytes('u coordinate', uEnc, montgomeryBytes);
156
- // u[fieldLen-1] crashes QuickJS (TypeError: out-of-bound numeric index)
157
- if (fieldLen === montgomeryBytes) u[fieldLen - 1] &= 127; // 0b0111_1111
154
+ if (fieldLen === 32) u[31] &= 127; // 0b0111_1111
158
155
  return bytesToNumberLE(u);
159
156
  }
160
157
  function decodeScalar(n: Hex): bigint {
161
158
  const bytes = ensureBytes('scalar', n);
162
- if (bytes.length !== montgomeryBytes && bytes.length !== fieldLen)
163
- throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
159
+ const len = bytes.length;
160
+ if (len !== montgomeryBytes && len !== fieldLen)
161
+ throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${len}`);
164
162
  return bytesToNumberLE(adjustScalarBytes(bytes));
165
163
  }
166
164
  function scalarMult(scalar: Hex, u: Hex): Uint8Array {
@@ -6,7 +6,6 @@
6
6
  const _0n = BigInt(0);
7
7
  const _1n = BigInt(1);
8
8
  const _2n = BigInt(2);
9
- const u8a = (a: any): a is Uint8Array => a instanceof Uint8Array;
10
9
  export type Hex = Uint8Array | string; // hex strings are accepted for simplicity
11
10
  export type PrivKey = Hex | bigint; // bigints are accepted to ease learning curve
12
11
  export type CHash = {
@@ -17,6 +16,18 @@ export type CHash = {
17
16
  };
18
17
  export type FHash = (message: Uint8Array | string) => Uint8Array;
19
18
 
19
+ export function isBytes(a: unknown): a is Uint8Array {
20
+ return (
21
+ a instanceof Uint8Array ||
22
+ (a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array')
23
+ );
24
+ }
25
+
26
+ export function abytes(item: unknown): void {
27
+ if (!isBytes(item)) throw new Error('Uint8Array expected');
28
+ }
29
+
30
+ // Array where index 0xf0 (240) is mapped to string 'f0'
20
31
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
21
32
  i.toString(16).padStart(2, '0')
22
33
  );
@@ -24,7 +35,7 @@ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
24
35
  * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
25
36
  */
26
37
  export function bytesToHex(bytes: Uint8Array): string {
27
- if (!u8a(bytes)) throw new Error('Uint8Array expected');
38
+ abytes(bytes);
28
39
  // pre-caching improves the speed 6x
29
40
  let hex = '';
30
41
  for (let i = 0; i < bytes.length; i++) {
@@ -44,20 +55,32 @@ export function hexToNumber(hex: string): bigint {
44
55
  return BigInt(hex === '' ? '0' : `0x${hex}`);
45
56
  }
46
57
 
58
+ // We use optimized technique to convert hex string to byte array
59
+ const asciis = { _0: 48, _9: 57, _A: 65, _F: 70, _a: 97, _f: 102 } as const;
60
+ function asciiToBase16(char: number): number | undefined {
61
+ if (char >= asciis._0 && char <= asciis._9) return char - asciis._0;
62
+ if (char >= asciis._A && char <= asciis._F) return char - (asciis._A - 10);
63
+ if (char >= asciis._a && char <= asciis._f) return char - (asciis._a - 10);
64
+ return;
65
+ }
66
+
47
67
  /**
48
68
  * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
49
69
  */
50
70
  export function hexToBytes(hex: string): Uint8Array {
51
71
  if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
52
- const len = hex.length;
53
- if (len % 2) throw new Error('padded hex string expected, got unpadded hex of length ' + len);
54
- const array = new Uint8Array(len / 2);
55
- for (let i = 0; i < array.length; i++) {
56
- const j = i * 2;
57
- const hexByte = hex.slice(j, j + 2);
58
- const byte = Number.parseInt(hexByte, 16);
59
- if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');
60
- array[i] = byte;
72
+ const hl = hex.length;
73
+ const al = hl / 2;
74
+ if (hl % 2) throw new Error('padded hex string expected, got unpadded hex of length ' + hl);
75
+ const array = new Uint8Array(al);
76
+ for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
77
+ const n1 = asciiToBase16(hex.charCodeAt(hi));
78
+ const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
79
+ if (n1 === undefined || n2 === undefined) {
80
+ const char = hex[hi] + hex[hi + 1];
81
+ throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
82
+ }
83
+ array[ai] = n1 * 16 + n2;
61
84
  }
62
85
  return array;
63
86
  }
@@ -67,7 +90,7 @@ export function bytesToNumberBE(bytes: Uint8Array): bigint {
67
90
  return hexToNumber(bytesToHex(bytes));
68
91
  }
69
92
  export function bytesToNumberLE(bytes: Uint8Array): bigint {
70
- if (!u8a(bytes)) throw new Error('Uint8Array expected');
93
+ abytes(bytes);
71
94
  return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
72
95
  }
73
96
 
@@ -99,7 +122,7 @@ export function ensureBytes(title: string, hex: Hex, expectedLength?: number): U
99
122
  } catch (e) {
100
123
  throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`);
101
124
  }
102
- } else if (u8a(hex)) {
125
+ } else if (isBytes(hex)) {
103
126
  // Uint8Array.from() instead of hash.slice() because node.js Buffer
104
127
  // is instance of Uint8Array, and its slice() creates **mutable** copy
105
128
  res = Uint8Array.from(hex);
@@ -116,21 +139,27 @@ export function ensureBytes(title: string, hex: Hex, expectedLength?: number): U
116
139
  * Copies several Uint8Arrays into one.
117
140
  */
118
141
  export function concatBytes(...arrays: Uint8Array[]): Uint8Array {
119
- const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
120
- let pad = 0; // walk through each item, ensure they have proper type
121
- arrays.forEach((a) => {
122
- if (!u8a(a)) throw new Error('Uint8Array expected');
123
- r.set(a, pad);
142
+ let sum = 0;
143
+ for (let i = 0; i < arrays.length; i++) {
144
+ const a = arrays[i];
145
+ abytes(a);
146
+ sum += a.length;
147
+ }
148
+ const res = new Uint8Array(sum);
149
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
150
+ const a = arrays[i];
151
+ res.set(a, pad);
124
152
  pad += a.length;
125
- });
126
- return r;
153
+ }
154
+ return res;
127
155
  }
128
156
 
129
- export function equalBytes(b1: Uint8Array, b2: Uint8Array) {
130
- // We don't care about timing attacks here
131
- if (b1.length !== b2.length) return false;
132
- for (let i = 0; i < b1.length; i++) if (b1[i] !== b2[i]) return false;
133
- return true;
157
+ // Compares 2 u8a-s in kinda constant time
158
+ export function equalBytes(a: Uint8Array, b: Uint8Array) {
159
+ if (a.length !== b.length) return false;
160
+ let diff = 0;
161
+ for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
162
+ return diff === 0;
134
163
  }
135
164
 
136
165
  // Global symbols in both browsers and Node.js since v11
@@ -169,9 +198,9 @@ export function bitGet(n: bigint, pos: number) {
169
198
  /**
170
199
  * Sets single bit at position.
171
200
  */
172
- export const bitSet = (n: bigint, pos: number, value: boolean) => {
201
+ export function bitSet(n: bigint, pos: number, value: boolean) {
173
202
  return n | ((value ? _1n : _0n) << BigInt(pos));
174
- };
203
+ }
175
204
 
176
205
  /**
177
206
  * Calculate mask for N bits. Not using ** operator with bigints because of old engines.
@@ -248,7 +277,7 @@ const validatorFns = {
248
277
  function: (val: any) => typeof val === 'function',
249
278
  boolean: (val: any) => typeof val === 'boolean',
250
279
  string: (val: any) => typeof val === 'string',
251
- stringOrUint8Array: (val: any) => typeof val === 'string' || val instanceof Uint8Array,
280
+ stringOrUint8Array: (val: any) => typeof val === 'string' || isBytes(val),
252
281
  isSafeInteger: (val: any) => Number.isSafeInteger(val),
253
282
  array: (val: any) => Array.isArray(val),
254
283
  field: (val: any, object: any) => (object as any).Fp.isValid(val),
@@ -27,7 +27,7 @@ export type BasicWCurve<T> = BasicCurve<T> & {
27
27
  clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
28
28
  };
29
29
 
30
- type Entropy = Hex | true;
30
+ type Entropy = Hex | boolean;
31
31
  export type SignOpts = { lowS?: boolean; extraEntropy?: Entropy; prehash?: boolean };
32
32
  export type VerOpts = { lowS?: boolean; prehash?: boolean };
33
33
 
@@ -123,6 +123,7 @@ function validatePointOpts<T>(curve: CurvePointsType<T>) {
123
123
  }
124
124
 
125
125
  export type CurvePointsRes<T> = {
126
+ CURVE: ReturnType<typeof validatePointOpts<T>>;
126
127
  ProjectivePoint: ProjConstructor<T>;
127
128
  normPrivateKeyToScalar: (key: PrivKey) => bigint;
128
129
  weierstrassEquation: (x: T) => T;
@@ -157,7 +158,7 @@ export const DER = {
157
158
  // parse DER signature
158
159
  const { Err: E } = DER;
159
160
  const data = typeof hex === 'string' ? h2b(hex) : hex;
160
- if (!(data instanceof Uint8Array)) throw new Error('ui8a expected');
161
+ ut.abytes(data);
161
162
  let l = data.length;
162
163
  if (l < 2 || data[0] != 0x30) throw new E('Invalid signature tag');
163
164
  if (data[1] !== l - 2) throw new E('Invalid signature: incorrect length');
@@ -187,7 +188,7 @@ export const DER = {
187
188
  // prettier-ignore
188
189
  const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
189
190
 
190
- export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
191
+ export function weierstrassPoints<T>(opts: CurvePointsType<T>): CurvePointsRes<T> {
191
192
  const CURVE = validatePointOpts(opts);
192
193
  const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
193
194
 
@@ -237,7 +238,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
237
238
  function normPrivateKeyToScalar(key: PrivKey): bigint {
238
239
  const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
239
240
  if (lengths && typeof key !== 'bigint') {
240
- if (key instanceof Uint8Array) key = ut.bytesToHex(key);
241
+ if (ut.isBytes(key)) key = ut.bytesToHex(key);
241
242
  // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
242
243
  if (typeof key !== 'string' || !lengths.includes(key.length)) throw new Error('Invalid key');
243
244
  key = key.padStart(nByteLength * 2, '0');
@@ -269,7 +270,11 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
269
270
  static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
270
271
  static readonly ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
271
272
 
272
- constructor(readonly px: T, readonly py: T, readonly pz: T) {
273
+ constructor(
274
+ readonly px: T,
275
+ readonly py: T,
276
+ readonly pz: T
277
+ ) {
273
278
  if (px == null || !Fp.isValid(px)) throw new Error('x required');
274
279
  if (py == null || !Fp.isValid(py)) throw new Error('y required');
275
280
  if (pz == null || !Fp.isValid(pz)) throw new Error('z required');
@@ -728,7 +733,13 @@ export function weierstrass(curveDef: CurveType): CurveFn {
728
733
  const x = ut.bytesToNumberBE(tail);
729
734
  if (!isValidFieldElement(x)) throw new Error('Point is not on curve');
730
735
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
731
- let y = Fp.sqrt(y2); // y = y² ^ (p+1)/4
736
+ let y: bigint;
737
+ try {
738
+ y = Fp.sqrt(y2); // y = y² ^ (p+1)/4
739
+ } catch (sqrtError) {
740
+ const suffix = sqrtError instanceof Error ? ': ' + sqrtError.message : '';
741
+ throw new Error('Point is not on curve' + suffix);
742
+ }
732
743
  const isYOdd = (y & _1n) === _1n;
733
744
  // ECDSA
734
745
  const isHeadOdd = (head & 1) === 1;
@@ -763,7 +774,11 @@ export function weierstrass(curveDef: CurveType): CurveFn {
763
774
  * ECDSA signature with its (r, s) properties. Supports DER & compact representations.
764
775
  */
765
776
  class Signature implements SignatureType {
766
- constructor(readonly r: bigint, readonly s: bigint, readonly recovery?: number) {
777
+ constructor(
778
+ readonly r: bigint,
779
+ readonly s: bigint,
780
+ readonly recovery?: number
781
+ ) {
767
782
  this.assertValidity();
768
783
  }
769
784
 
@@ -884,7 +899,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
884
899
  * Quick and dirty check for item being public key. Does not validate hex, or being on-curve.
885
900
  */
886
901
  function isProbPub(item: PrivKey | PubKey): boolean {
887
- const arr = item instanceof Uint8Array;
902
+ const arr = ut.isBytes(item);
888
903
  const str = typeof item === 'string';
889
904
  const len = (arr || str) && (item as Hex).length;
890
905
  if (arr) return len === compressedLen || len === uncompressedLen;
@@ -962,7 +977,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
962
977
  const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint
963
978
  const seedArgs = [int2octets(d), int2octets(h1int)];
964
979
  // extraEntropy. RFC6979 3.6: additional k' (optional).
965
- if (ent != null) {
980
+ if (ent != null && ent !== false) {
966
981
  // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
967
982
  const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
968
983
  seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
@@ -1048,7 +1063,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
1048
1063
  let _sig: Signature | undefined = undefined;
1049
1064
  let P: ProjPointType<bigint>;
1050
1065
  try {
1051
- if (typeof sg === 'string' || sg instanceof Uint8Array) {
1066
+ if (typeof sg === 'string' || ut.isBytes(sg)) {
1052
1067
  // Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
1053
1068
  // Since DER can also be 2*nByteLength bytes, we check for it first.
1054
1069
  try {