@noble/curves 1.3.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.
@@ -83,12 +83,12 @@ export type CurveFn<Fp, Fp2, Fp6, Fp12> = {
83
83
  getPublicKey: (privateKey: PrivKey) => Uint8Array;
84
84
  getPublicKeyForShortSignatures: (privateKey: PrivKey) => Uint8Array;
85
85
  sign: {
86
- (message: Hex, privateKey: PrivKey): Uint8Array;
87
- (message: ProjPointType<Fp2>, privateKey: PrivKey): ProjPointType<Fp2>;
86
+ (message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
87
+ (message: ProjPointType<Fp2>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp2>;
88
88
  };
89
89
  signShortSignature: {
90
- (message: Hex, privateKey: PrivKey): Uint8Array;
91
- (message: ProjPointType<Fp>, privateKey: PrivKey): ProjPointType<Fp>;
90
+ (message: Hex, privateKey: PrivKey, htfOpts?: htfBasicOpts): Uint8Array;
91
+ (message: ProjPointType<Fp>, privateKey: PrivKey, htfOpts?: htfBasicOpts): ProjPointType<Fp>;
92
92
  };
93
93
  verify: (
94
94
  signature: Hex | ProjPointType<Fp2>,
@@ -2,7 +2,7 @@
2
2
  import type { Group, GroupConstructor, AffinePoint } from './curve.js';
3
3
  import { mod, IField } from './modular.js';
4
4
  import type { CHash } from './utils.js';
5
- import { bytesToNumberBE, isBytes, concatBytes, utf8ToBytes, validateObject } from './utils.js';
5
+ import { bytesToNumberBE, abytes, concatBytes, utf8ToBytes, validateObject } from './utils.js';
6
6
 
7
7
  /**
8
8
  * * `DST` is a domain separation tag, defined in section 2.2.5
@@ -22,12 +22,6 @@ export type Opts = {
22
22
  hash: CHash;
23
23
  };
24
24
 
25
- function validateDST(dst: UnicodeOrBytes): Uint8Array {
26
- if (isBytes(dst)) return dst;
27
- if (typeof dst === 'string') return utf8ToBytes(dst);
28
- throw new Error('DST must be Uint8Array or string');
29
- }
30
-
31
25
  // Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
32
26
  const os2ip = bytesToNumberBE;
33
27
 
@@ -52,10 +46,7 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
52
46
  return arr;
53
47
  }
54
48
 
55
- function abytes(item: unknown): void {
56
- if (!isBytes(item)) throw new Error('Uint8Array expected');
57
- }
58
- function isNum(item: unknown): void {
49
+ function anum(item: unknown): void {
59
50
  if (!Number.isSafeInteger(item)) throw new Error('number expected');
60
51
  }
61
52
 
@@ -69,7 +60,7 @@ export function expand_message_xmd(
69
60
  ): Uint8Array {
70
61
  abytes(msg);
71
62
  abytes(DST);
72
- isNum(lenInBytes);
63
+ anum(lenInBytes);
73
64
  // https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
74
65
  if (DST.length > 255) DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
75
66
  const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
@@ -103,7 +94,7 @@ export function expand_message_xof(
103
94
  ): Uint8Array {
104
95
  abytes(msg);
105
96
  abytes(DST);
106
- isNum(lenInBytes);
97
+ anum(lenInBytes);
107
98
  // https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
108
99
  // DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
109
100
  if (DST.length > 255) {
@@ -141,8 +132,8 @@ export function hash_to_field(msg: Uint8Array, count: number, options: Opts): bi
141
132
  });
142
133
  const { p, k, m, hash, expand, DST: _DST } = options;
143
134
  abytes(msg);
144
- isNum(count);
145
- const DST = validateDST(_DST);
135
+ anum(count);
136
+ const DST = typeof _DST === 'string' ? utf8ToBytes(_DST) : _DST;
146
137
  const log2p = p.toString(2).length;
147
138
  const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
148
139
  const len_in_bytes = count * m * L;
@@ -23,6 +23,10 @@ export function isBytes(a: unknown): a is Uint8Array {
23
23
  );
24
24
  }
25
25
 
26
+ export function abytes(item: unknown): void {
27
+ if (!isBytes(item)) throw new Error('Uint8Array expected');
28
+ }
29
+
26
30
  // Array where index 0xf0 (240) is mapped to string 'f0'
27
31
  const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
28
32
  i.toString(16).padStart(2, '0')
@@ -31,7 +35,7 @@ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
31
35
  * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
32
36
  */
33
37
  export function bytesToHex(bytes: Uint8Array): string {
34
- if (!isBytes(bytes)) throw new Error('Uint8Array expected');
38
+ abytes(bytes);
35
39
  // pre-caching improves the speed 6x
36
40
  let hex = '';
37
41
  for (let i = 0; i < bytes.length; i++) {
@@ -86,7 +90,7 @@ export function bytesToNumberBE(bytes: Uint8Array): bigint {
86
90
  return hexToNumber(bytesToHex(bytes));
87
91
  }
88
92
  export function bytesToNumberLE(bytes: Uint8Array): bigint {
89
- if (!isBytes(bytes)) throw new Error('Uint8Array expected');
93
+ abytes(bytes);
90
94
  return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
91
95
  }
92
96
 
@@ -138,12 +142,11 @@ export function concatBytes(...arrays: Uint8Array[]): Uint8Array {
138
142
  let sum = 0;
139
143
  for (let i = 0; i < arrays.length; i++) {
140
144
  const a = arrays[i];
141
- if (!isBytes(a)) throw new Error('Uint8Array expected');
145
+ abytes(a);
142
146
  sum += a.length;
143
147
  }
144
- let res = new Uint8Array(sum);
145
- let pad = 0;
146
- for (let i = 0; i < arrays.length; i++) {
148
+ const res = new Uint8Array(sum);
149
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
147
150
  const a = arrays[i];
148
151
  res.set(a, pad);
149
152
  pad += a.length;
@@ -195,9 +198,9 @@ export function bitGet(n: bigint, pos: number) {
195
198
  /**
196
199
  * Sets single bit at position.
197
200
  */
198
- export const bitSet = (n: bigint, pos: number, value: boolean) => {
201
+ export function bitSet(n: bigint, pos: number, value: boolean) {
199
202
  return n | ((value ? _1n : _0n) << BigInt(pos));
200
- };
203
+ }
201
204
 
202
205
  /**
203
206
  * Calculate mask for N bits. Not using ** operator with bigints because of old engines.
@@ -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
 
@@ -158,7 +158,7 @@ export const DER = {
158
158
  // parse DER signature
159
159
  const { Err: E } = DER;
160
160
  const data = typeof hex === 'string' ? h2b(hex) : hex;
161
- if (!ut.isBytes(data)) throw new Error('ui8a expected');
161
+ ut.abytes(data);
162
162
  let l = data.length;
163
163
  if (l < 2 || data[0] != 0x30) throw new E('Invalid signature tag');
164
164
  if (data[1] !== l - 2) throw new E('Invalid signature: incorrect length');
@@ -733,7 +733,13 @@ export function weierstrass(curveDef: CurveType): CurveFn {
733
733
  const x = ut.bytesToNumberBE(tail);
734
734
  if (!isValidFieldElement(x)) throw new Error('Point is not on curve');
735
735
  const y2 = weierstrassEquation(x); // y² = x³ + ax + b
736
- 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
+ }
737
743
  const isYOdd = (y & _1n) === _1n;
738
744
  // ECDSA
739
745
  const isHeadOdd = (head & 1) === 1;
@@ -971,7 +977,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
971
977
  const d = normPrivateKeyToScalar(privateKey); // validate private key, convert to bigint
972
978
  const seedArgs = [int2octets(d), int2octets(h1int)];
973
979
  // extraEntropy. RFC6979 3.6: additional k' (optional).
974
- if (ent != null) {
980
+ if (ent != null && ent !== false) {
975
981
  // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
976
982
  const e = ent === true ? randomBytes(Fp.BYTES) : ent; // generate random bytes OR pass as-is
977
983
  seedArgs.push(ensureBytes('extraEntropy', e)); // check for being bytes
package/src/bls12-381.ts CHANGED
@@ -1364,7 +1364,7 @@ export const bls12_381: CurveFn<Fp, Fp2, Fp6, Fp12> = bls({
1364
1364
  fromHex(hex: Hex): ProjPointType<Fp2> {
1365
1365
  const { infinity, sort, value } = parseMask(ensureBytes('signatureHex', hex));
1366
1366
  const P = Fp.ORDER;
1367
- const half = hex.length / 2;
1367
+ const half = value.length / 2;
1368
1368
  if (half !== 48 && half !== 96)
1369
1369
  throw new Error('Invalid compressed signature length, must be 96 or 192');
1370
1370
  const z1 = bytesToNumberBE(value.slice(0, half));
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }