@noble/curves 0.6.0 → 0.6.1

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.
@@ -1,31 +1,19 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  import { mod, pow } from './modular.js';
3
- import { ensureBytes, numberToBytesLE, bytesToNumberLE } from './utils.js';
3
+ import { bytesToNumberLE, ensureBytes, numberToBytesLE, validateObject } from './utils.js';
4
4
  const _0n = BigInt(0);
5
5
  const _1n = BigInt(1);
6
6
  function validateOpts(curve) {
7
- for (const i of ['a24']) {
8
- if (typeof curve[i] !== 'bigint')
9
- throw new Error(`Invalid curve param ${i}=${curve[i]} (${typeof curve[i]})`);
10
- }
11
- for (const i of ['montgomeryBits', 'nByteLength']) {
12
- if (curve[i] === undefined)
13
- continue; // Optional
14
- if (!Number.isSafeInteger(curve[i]))
15
- throw new Error(`Invalid curve param ${i}=${curve[i]} (${typeof curve[i]})`);
16
- }
17
- for (const fn of ['adjustScalarBytes', 'domain', 'powPminus2']) {
18
- if (curve[fn] === undefined)
19
- continue; // Optional
20
- if (typeof curve[fn] !== 'function')
21
- throw new Error(`Invalid ${fn} function`);
22
- }
23
- for (const i of ['Gu']) {
24
- if (curve[i] === undefined)
25
- continue; // Optional
26
- if (typeof curve[i] !== 'string')
27
- throw new Error(`Invalid curve param ${i}=${curve[i]} (${typeof curve[i]})`);
28
- }
7
+ validateObject(curve, {
8
+ a24: 'bigint',
9
+ }, {
10
+ montgomeryBits: 'isSafeInteger',
11
+ nByteLength: 'isSafeInteger',
12
+ adjustScalarBytes: 'function',
13
+ domain: 'function',
14
+ powPminus2: 'function',
15
+ Gu: 'string',
16
+ });
29
17
  // Set defaults
30
18
  return Object.freeze({ ...curve });
31
19
  }
@@ -40,31 +28,7 @@ export function montgomery(curveDef) {
40
28
  const fieldLen = CURVE.nByteLength;
41
29
  const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes);
42
30
  const powPminus2 = CURVE.powPminus2 || ((x) => pow(x, P - BigInt(2), P));
43
- /**
44
- * Checks for num to be in range:
45
- * For strict == true: `0 < num < max`.
46
- * For strict == false: `0 <= num < max`.
47
- * Converts non-float safe numbers to bigints.
48
- */
49
- function normalizeScalar(num, max, strict = true) {
50
- if (!max)
51
- throw new TypeError('Specify max value');
52
- if (typeof num === 'number' && Number.isSafeInteger(num))
53
- num = BigInt(num);
54
- if (typeof num === 'bigint' && num < max) {
55
- if (strict) {
56
- if (_0n < num)
57
- return num;
58
- }
59
- else {
60
- if (_0n <= num)
61
- return num;
62
- }
63
- }
64
- throw new TypeError('Expected valid scalar: 0 < scalar < max');
65
- }
66
- // cswap from RFC7748
67
- // NOTE: cswap is not from RFC7748!
31
+ // cswap from RFC7748. But it is not from RFC7748!
68
32
  /*
69
33
  cswap(swap, x_2, x_3):
70
34
  dummy = mask(swap) AND (x_2 XOR x_3)
@@ -80,6 +44,11 @@ export function montgomery(curveDef) {
80
44
  x_3 = modP(x_3 + dummy);
81
45
  return [x_2, x_3];
82
46
  }
47
+ function assertFieldElement(n) {
48
+ if (typeof n === 'bigint' && _0n <= n && n < P)
49
+ return n;
50
+ throw new Error('Expected valid scalar 0 < scalar < CURVE.P');
51
+ }
83
52
  // x25519 from 4
84
53
  /**
85
54
  *
@@ -88,11 +57,10 @@ export function montgomery(curveDef) {
88
57
  * @returns new Point on Montgomery curve
89
58
  */
90
59
  function montgomeryLadder(pointU, scalar) {
91
- const { P } = CURVE;
92
- const u = normalizeScalar(pointU, P);
60
+ const u = assertFieldElement(pointU);
93
61
  // Section 5: Implementations MUST accept non-canonical values and process them as
94
62
  // if they had been reduced modulo the field prime.
95
- const k = normalizeScalar(scalar, P);
63
+ const k = assertFieldElement(scalar);
96
64
  // The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519
97
65
  const a24 = CURVE.a24;
98
66
  const x_1 = u;
@@ -145,11 +113,11 @@ export function montgomery(curveDef) {
145
113
  return numberToBytesLE(modP(u), montgomeryBytes);
146
114
  }
147
115
  function decodeUCoordinate(uEnc) {
148
- const u = ensureBytes(uEnc, montgomeryBytes);
149
116
  // Section 5: When receiving such an array, implementations of X25519
150
117
  // MUST mask the most significant bit in the final byte.
151
118
  // This is very ugly way, but it works because fieldLen-1 is outside of bounds for X448, so this becomes NOOP
152
119
  // fieldLen - scalaryBytes = 1 for X448 and = 0 for X25519
120
+ const u = ensureBytes(uEnc, montgomeryBytes);
153
121
  u[fieldLen - 1] &= 127; // 0b0111_1111
154
122
  return bytesToNumberLE(u);
155
123
  }
@@ -159,13 +127,6 @@ export function montgomery(curveDef) {
159
127
  throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
160
128
  return bytesToNumberLE(adjustScalarBytes(bytes));
161
129
  }
162
- /**
163
- * Computes shared secret between private key "scalar" and public key's "u" (x) coordinate.
164
- * We can get 'y' coordinate from 'u',
165
- * but Point.fromHex also wants 'x' coordinate oddity flag,
166
- * and we cannot get 'x' without knowing 'v'.
167
- * Need to add generic conversion between twisted edwards and complimentary curve for JubJub.
168
- */
169
130
  function scalarMult(scalar, u) {
170
131
  const pointU = decodeUCoordinate(u);
171
132
  const _scalar = decodeScalar(scalar);
@@ -176,12 +137,7 @@ export function montgomery(curveDef) {
176
137
  throw new Error('Invalid private or public key received');
177
138
  return encodeUCoordinate(pu);
178
139
  }
179
- /**
180
- * Computes public key from private.
181
- * Executes scalar multiplication of curve's base point by scalar.
182
- * @param scalar private key
183
- * @returns new public key
184
- */
140
+ // Computes public key from private. By doing scalar multiplication of base point.
185
141
  function scalarMultBase(scalar) {
186
142
  return scalarMult(scalar, CURVE.Gu);
187
143
  }
@@ -1,6 +1,6 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  // Poseidon Hash: https://eprint.iacr.org/2019/458.pdf, https://www.poseidon-hash.info
3
- import { validateField, FpPow } from './modular.js';
3
+ import { FpPow, validateField } from './modular.js';
4
4
  export function validateOpts(opts) {
5
5
  const { Fp } = opts;
6
6
  validateField(Fp);
@@ -6,7 +6,7 @@ const u8a = (a) => a instanceof Uint8Array;
6
6
  const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
7
7
  export function bytesToHex(bytes) {
8
8
  if (!u8a(bytes))
9
- throw new Error('Expected Uint8Array');
9
+ throw new Error('Uint8Array expected');
10
10
  // pre-caching improves the speed 6x
11
11
  let hex = '';
12
12
  for (let i = 0; i < bytes.length; i++) {
@@ -20,23 +20,23 @@ export function numberToHexUnpadded(num) {
20
20
  }
21
21
  export function hexToNumber(hex) {
22
22
  if (typeof hex !== 'string')
23
- throw new Error('hexToNumber: expected string, got ' + typeof hex);
23
+ throw new Error('string expected, got ' + typeof hex);
24
24
  // Big Endian
25
25
  return BigInt(`0x${hex}`);
26
26
  }
27
27
  // Caching slows it down 2-3x
28
28
  export function hexToBytes(hex) {
29
29
  if (typeof hex !== 'string')
30
- throw new Error('hexToBytes: expected string, got ' + typeof hex);
30
+ throw new Error('string expected, got ' + typeof hex);
31
31
  if (hex.length % 2)
32
- throw new Error('hexToBytes: received invalid unpadded hex ' + hex.length);
32
+ throw new Error('hex string is invalid: unpadded ' + hex.length);
33
33
  const array = new Uint8Array(hex.length / 2);
34
34
  for (let i = 0; i < array.length; i++) {
35
35
  const j = i * 2;
36
36
  const hexByte = hex.slice(j, j + 2);
37
37
  const byte = Number.parseInt(hexByte, 16);
38
38
  if (Number.isNaN(byte) || byte < 0)
39
- throw new Error('Invalid byte sequence');
39
+ throw new Error('invalid byte sequence');
40
40
  array[i] = byte;
41
41
  }
42
42
  return array;
@@ -47,18 +47,13 @@ export function bytesToNumberBE(bytes) {
47
47
  }
48
48
  export function bytesToNumberLE(bytes) {
49
49
  if (!u8a(bytes))
50
- throw new Error('Expected Uint8Array');
50
+ throw new Error('Uint8Array expected');
51
51
  return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
52
52
  }
53
53
  export const numberToBytesBE = (n, len) => hexToBytes(n.toString(16).padStart(len * 2, '0'));
54
54
  export const numberToBytesLE = (n, len) => numberToBytesBE(n, len).reverse();
55
55
  // Returns variable number bytes (minimal bigint encoding?)
56
- export const numberToVarBytesBE = (n) => {
57
- let hex = n.toString(16);
58
- if (hex.length & 1)
59
- hex = '0' + hex;
60
- return hexToBytes(hex);
61
- };
56
+ export const numberToVarBytesBE = (n) => hexToBytes(numberToHexUnpadded(n));
62
57
  export function ensureBytes(hex, expectedLength) {
63
58
  // Uint8Array.from() instead of hash.slice() because node.js Buffer
64
59
  // is instance of Uint8Array, and its slice() creates **mutable** copy
@@ -68,19 +63,16 @@ export function ensureBytes(hex, expectedLength) {
68
63
  return bytes;
69
64
  }
70
65
  // Copies several Uint8Arrays into one.
71
- export function concatBytes(...arrays) {
72
- if (!arrays.every((b) => u8a(b)))
73
- throw new Error('Uint8Array list expected');
74
- if (arrays.length === 1)
75
- return arrays[0];
76
- const length = arrays.reduce((a, arr) => a + arr.length, 0);
77
- const result = new Uint8Array(length);
78
- for (let i = 0, pad = 0; i < arrays.length; i++) {
79
- const arr = arrays[i];
80
- result.set(arr, pad);
81
- pad += arr.length;
82
- }
83
- return result;
66
+ export function concatBytes(...arrs) {
67
+ const r = new Uint8Array(arrs.reduce((sum, a) => sum + a.length, 0));
68
+ let pad = 0; // walk through each item, ensure they have proper type
69
+ arrs.forEach((a) => {
70
+ if (!u8a(a))
71
+ throw new Error('Uint8Array expected');
72
+ r.set(a, pad);
73
+ pad += a.length;
74
+ });
75
+ return r;
84
76
  }
85
77
  export function equalBytes(b1, b2) {
86
78
  // We don't care about timing attacks here
@@ -107,3 +99,32 @@ export const bitSet = (n, pos, value) => n | ((value ? _1n : _0n) << BigInt(pos)
107
99
  // Return mask for N bits (Same as BigInt(`0b${Array(i).fill('1').join('')}`))
108
100
  // Not using ** operator with bigints for old engines.
109
101
  export const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
102
+ export function validateObject(object, validators, optValidators = {}) {
103
+ const validatorFns = {
104
+ bigint: (val) => typeof val === 'bigint',
105
+ function: (val) => typeof val === 'function',
106
+ boolean: (val) => typeof val === 'boolean',
107
+ string: (val) => typeof val === 'string',
108
+ isSafeInteger: (val) => Number.isSafeInteger(val),
109
+ array: (val) => Array.isArray(val),
110
+ field: (val) => object.Fp.isValid(val),
111
+ hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
112
+ };
113
+ // type Key = keyof typeof validators;
114
+ const checkField = (fieldName, type, isOptional) => {
115
+ const checkVal = validatorFns[type];
116
+ if (typeof checkVal !== 'function')
117
+ throw new Error(`Invalid validator "${type}", expected function`);
118
+ const val = object[fieldName];
119
+ if (isOptional && val === undefined)
120
+ return;
121
+ if (!checkVal(val)) {
122
+ throw new Error(`Invalid param ${fieldName}=${val} (${typeof val}), expected ${type}`);
123
+ }
124
+ };
125
+ for (let [fieldName, type] of Object.entries(validators))
126
+ checkField(fieldName, type, false);
127
+ for (let [fieldName, type] of Object.entries(optValidators))
128
+ checkField(fieldName, type, true);
129
+ return object;
130
+ }
@@ -3,23 +3,23 @@
3
3
  import * as mod from './modular.js';
4
4
  import * as ut from './utils.js';
5
5
  import { ensureBytes } from './utils.js';
6
- import { wNAF, validateAbsOpts, } from './curve.js';
6
+ import { wNAF, validateBasic } from './curve.js';
7
7
  function validatePointOpts(curve) {
8
- const opts = validateAbsOpts(curve);
9
- const Fp = opts.Fp;
10
- for (const i of ['a', 'b']) {
11
- if (!Fp.isValid(curve[i]))
12
- throw new Error(`Invalid curve param ${i}=${opts[i]} (${typeof opts[i]})`);
13
- }
14
- for (const i of ['isTorsionFree', 'clearCofactor']) {
15
- if (curve[i] === undefined)
16
- continue; // Optional
17
- if (typeof curve[i] !== 'function')
18
- throw new Error(`Invalid ${i} function`);
19
- }
20
- const endo = opts.endo;
8
+ const opts = validateBasic(curve);
9
+ ut.validateObject(opts, {
10
+ a: 'field',
11
+ b: 'field',
12
+ fromBytes: 'function',
13
+ toBytes: 'function',
14
+ }, {
15
+ allowedPrivateKeyLengths: 'array',
16
+ wrapPrivateKey: 'boolean',
17
+ isTorsionFree: 'function',
18
+ clearCofactor: 'function',
19
+ });
20
+ const { endo, Fp, a } = opts;
21
21
  if (endo) {
22
- if (!Fp.eql(opts.a, Fp.ZERO)) {
22
+ if (!Fp.eql(a, Fp.ZERO)) {
23
23
  throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
24
24
  }
25
25
  if (typeof endo !== 'object' ||
@@ -28,11 +28,6 @@ function validatePointOpts(curve) {
28
28
  throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
29
29
  }
30
30
  }
31
- if (typeof opts.fromBytes !== 'function')
32
- throw new Error('Invalid fromBytes function');
33
- if (typeof opts.toBytes !== 'function')
34
- throw new Error('Invalid fromBytes function');
35
- // Set defaults
36
31
  return Object.freeze({ ...opts });
37
32
  }
38
33
  // ASN.1 DER encoding utilities
@@ -113,39 +108,28 @@ export function weierstrassPoints(opts) {
113
108
  if (!isWithinCurveOrder(num))
114
109
  throw new Error('Expected valid bigint: 0 < bigint < curve.n');
115
110
  }
116
- /**
117
- * Validates if a private key is valid and converts it to bigint form.
118
- * Supports two options, that are passed when CURVE is initialized:
119
- * - `normalizePrivateKey()` executed before all checks
120
- * - `wrapPrivateKey` when true, executed after most checks, but before `0 < key < n`
121
- */
111
+ // Validates if priv key is valid and converts it to bigint.
112
+ // Supports options CURVE.normalizePrivateKey and CURVE.wrapPrivateKey.
122
113
  function normalizePrivateKey(key) {
123
- const { normalizePrivateKey: custom, nByteLength: groupLen, wrapPrivateKey, n } = CURVE;
124
- if (typeof custom === 'function')
125
- key = custom(key);
126
- let num;
127
- if (typeof key === 'bigint') {
128
- // Curve order check is done below
129
- num = key;
114
+ const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
115
+ if (lengths && typeof key !== 'bigint') {
116
+ if (key instanceof Uint8Array)
117
+ key = ut.bytesToHex(key);
118
+ // Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
119
+ if (typeof key !== 'string' || !lengths.includes(key.length))
120
+ throw new Error('Invalid key');
121
+ key = key.padStart(nByteLength * 2, '0');
130
122
  }
131
- else if (typeof key === 'string') {
132
- if (key.length !== 2 * groupLen)
133
- throw new Error(`must be ${groupLen} bytes`);
134
- // Validates individual octets
135
- num = ut.bytesToNumberBE(ensureBytes(key));
136
- }
137
- else if (key instanceof Uint8Array) {
138
- if (key.length !== groupLen)
139
- throw new Error(`must be ${groupLen} bytes`);
140
- num = ut.bytesToNumberBE(key);
123
+ let num;
124
+ try {
125
+ num = typeof key === 'bigint' ? key : ut.bytesToNumberBE(ensureBytes(key, nByteLength));
141
126
  }
142
- else {
143
- throw new Error('private key must be bytes, hex or bigint, not ' + typeof key);
127
+ catch (error) {
128
+ throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
144
129
  }
145
- // Useful for curves with cofactor != 1
146
130
  if (wrapPrivateKey)
147
- num = mod.mod(num, n);
148
- assertGE(num);
131
+ num = mod.mod(num, n); // disabled by default, enabled for BLS
132
+ assertGE(num); // num in range [1..N-1]
149
133
  return num;
150
134
  }
151
135
  const pointPrecomputes = new Map();
@@ -499,14 +483,16 @@ export function weierstrassPoints(opts) {
499
483
  };
500
484
  }
501
485
  function validateOpts(curve) {
502
- const opts = validateAbsOpts(curve);
503
- if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
504
- throw new Error('Invalid hash function');
505
- if (typeof opts.hmac !== 'function')
506
- throw new Error('Invalid hmac function');
507
- if (typeof opts.randomBytes !== 'function')
508
- throw new Error('Invalid randomBytes function');
509
- // Set defaults
486
+ const opts = validateBasic(curve);
487
+ ut.validateObject(opts, {
488
+ hash: 'hash',
489
+ hmac: 'function',
490
+ randomBytes: 'function',
491
+ }, {
492
+ bits2int: 'function',
493
+ bits2int_modN: 'function',
494
+ lowS: 'boolean',
495
+ });
510
496
  return Object.freeze({ lowS: true, ...opts });
511
497
  }
512
498
  const u8n = (data) => new Uint8Array(data); // creates Uint8Array
@@ -615,7 +601,7 @@ export function weierstrass(curveDef) {
615
601
  return { x, y };
616
602
  }
617
603
  else {
618
- throw new Error(`Point.fromHex: received invalid point. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`);
604
+ throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`);
619
605
  }
620
606
  },
621
607
  });
@@ -677,7 +663,7 @@ export function weierstrass(curveDef) {
677
663
  const ir = invN(radj); // r^-1
678
664
  const u1 = modN(-h * ir); // -hr^-1
679
665
  const u2 = modN(s * ir); // sr^-1
680
- const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2); // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1)
666
+ const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2); // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1)
681
667
  if (!Q)
682
668
  throw new Error('point at infinify'); // unsafe is fine: no priv data leaked
683
669
  Q.assertValidity();
@@ -800,9 +786,10 @@ export function weierstrass(curveDef) {
800
786
  const ORDER_MASK = ut.bitMask(CURVE.nBitLength);
801
787
  function int2octets(num) {
802
788
  if (typeof num !== 'bigint')
803
- throw new Error('Expected bigint');
789
+ throw new Error('bigint expected');
804
790
  if (!(_0n <= num && num < ORDER_MASK))
805
- throw new Error(`Expected number < 2^${CURVE.nBitLength}`);
791
+ // n in [0..ORDER_MASK-1]
792
+ throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
806
793
  // works with order, can have different size than numToField!
807
794
  return ut.numberToBytesBE(num, CURVE.nByteLength);
808
795
  }
@@ -812,6 +799,7 @@ export function weierstrass(curveDef) {
812
799
  // NOTE: we cannot assume here that msgHash has same amount of bytes as curve order, this will be wrong at least for P521.
813
800
  // Also it can be bigger for P224 + SHA256
814
801
  function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
802
+ const { hash, randomBytes } = CURVE;
815
803
  if (msgHash == null)
816
804
  throw new Error(`sign: expected valid message hash, not "${msgHash}"`);
817
805
  if (['recovered', 'canonical'].some((k) => k in opts))
@@ -819,28 +807,20 @@ export function weierstrass(curveDef) {
819
807
  throw new Error('sign() legacy options not supported');
820
808
  let { lowS, prehash, extraEntropy: ent } = opts; // generates low-s sigs by default
821
809
  if (prehash)
822
- msgHash = CURVE.hash(ensureBytes(msgHash));
810
+ msgHash = hash(ensureBytes(msgHash));
823
811
  if (lowS == null)
824
- lowS = true; // RFC6979 3.2: we skip step A, because
825
- // Step A is ignored, since we already provide hash instead of msg
826
- // NOTE: instead of bits2int, we calling here truncateHash, since we need
827
- // custom truncation for stark. For other curves it is essentially same as calling bits2int + mod
828
- // However, we cannot later call bits2octets (which is truncateHash + int2octets), since nested bits2int is broken
829
- // for curves where nBitLength % 8 !== 0, so we unwrap it here as int2octets call.
830
- // const bits2octets = (bits)=>int2octets(bytesToNumberBE(truncateHash(bits)))
812
+ lowS = true; // RFC6979 3.2: we skip step A, because we already provide hash
813
+ // We can't later call bits2octets, since nested bits2int is broken for curves
814
+ // with nBitLength % 8 !== 0. Because of that, we unwrap it here as int2octets call.
815
+ // const bits2octets = (bits) => int2octets(bits2int_modN(bits))
831
816
  const h1int = bits2int_modN(ensureBytes(msgHash));
832
- const h1octets = int2octets(h1int);
833
- const d = normalizePrivateKey(privateKey);
834
- // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
835
- const seedArgs = [int2octets(d), h1octets];
817
+ const d = normalizePrivateKey(privateKey); // validate private key, convert to bigint
818
+ const seedArgs = [int2octets(d), int2octets(h1int)];
819
+ // extraEntropy. RFC6979 3.6: additional k' (optional).
836
820
  if (ent != null) {
837
- // RFC6979 3.6: additional k' (optional)
838
- if (ent === true)
839
- ent = CURVE.randomBytes(Fp.BYTES);
840
- const e = ensureBytes(ent);
841
- if (e.length !== Fp.BYTES)
842
- throw new Error(`sign: Expected ${Fp.BYTES} bytes of extra data`);
843
- seedArgs.push(e);
821
+ // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')
822
+ // Either pass as-is, or generate random bytes. Then validate for being ui8a of size BYTES
823
+ seedArgs.push(ensureBytes(ent === true ? randomBytes(Fp.BYTES) : ent, Fp.BYTES));
844
824
  }
845
825
  const seed = ut.concatBytes(...seedArgs); // Step D of RFC6979 3.2
846
826
  const m = h1int; // NOTE: no need to call bits2int second time here, it is inside truncateHash!
@@ -950,7 +930,6 @@ export function weierstrass(curveDef) {
950
930
  getSharedSecret,
951
931
  sign,
952
932
  verify,
953
- // Point,
954
933
  ProjectivePoint: Point,
955
934
  Signature,
956
935
  utils,
package/lib/esm/p224.js CHANGED
@@ -8,7 +8,7 @@ export const P224 = createCurve({
8
8
  // Params: a, b
9
9
  a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'),
10
10
  b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'),
11
- // Field over which we'll do calculations; 2n**224n - 2n**96n + 1n
11
+ // Field over which we'll do calculations;
12
12
  Fp: Fp(BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001')),
13
13
  // Curve order, total count of valid points in the field
14
14
  n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'),
package/lib/esm/p521.js CHANGED
@@ -1,7 +1,6 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  import { createCurve } from './_shortw_utils.js';
3
3
  import { sha512 } from '@noble/hashes/sha512';
4
- import { bytesToHex } from './abstract/utils.js';
5
4
  import { Fp as Field } from './abstract/modular.js';
6
5
  import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
7
6
  import * as htf from './abstract/hash-to-curve.js';
@@ -33,18 +32,7 @@ export const P521 = createCurve({
33
32
  Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
34
33
  h: BigInt(1),
35
34
  lowS: false,
36
- // P521 keys could be 130, 131, 132 bytes. We normalize to 132 bytes.
37
- // Does not replace validation; invalid keys would still be rejected.
38
- normalizePrivateKey(key) {
39
- if (typeof key === 'bigint')
40
- return key;
41
- if (key instanceof Uint8Array)
42
- key = bytesToHex(key);
43
- if (typeof key !== 'string' || !([130, 131, 132].includes(key.length))) {
44
- throw new Error('Invalid key');
45
- }
46
- return key.padStart(66 * 2, '0'); // ensure it's always 132 bytes
47
- },
35
+ allowedPrivateKeyLengths: [130, 131, 132] // P521 keys are variable-length. Normalize to 132b
48
36
  }, sha512);
49
37
  export const secp521r1 = P521;
50
38
  const { hashToCurve, encodeToCurve } = htf.hashToCurve(secp521r1.ProjectivePoint, (scalars) => mapSWU(scalars[0]), {