@noble/curves 0.5.2 → 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.
Files changed (61) hide show
  1. package/README.md +115 -41
  2. package/lib/_shortw_utils.d.ts +13 -24
  3. package/lib/abstract/bls.d.ts +39 -32
  4. package/lib/abstract/bls.js +74 -73
  5. package/lib/abstract/{group.d.ts → curve.d.ts} +30 -1
  6. package/lib/abstract/{group.js → curve.js} +33 -2
  7. package/lib/abstract/edwards.d.ts +30 -72
  8. package/lib/abstract/edwards.js +206 -389
  9. package/lib/abstract/hash-to-curve.d.ts +25 -6
  10. package/lib/abstract/hash-to-curve.js +40 -12
  11. package/lib/abstract/modular.d.ts +21 -8
  12. package/lib/abstract/modular.js +72 -48
  13. package/lib/abstract/montgomery.js +23 -68
  14. package/lib/abstract/poseidon.d.ts +29 -0
  15. package/lib/abstract/poseidon.js +115 -0
  16. package/lib/abstract/utils.d.ts +9 -37
  17. package/lib/abstract/utils.js +61 -87
  18. package/lib/abstract/weierstrass.d.ts +58 -81
  19. package/lib/abstract/weierstrass.js +485 -679
  20. package/lib/bls12-381.js +63 -58
  21. package/lib/bn.js +1 -1
  22. package/lib/ed25519.d.ts +7 -5
  23. package/lib/ed25519.js +82 -79
  24. package/lib/ed448.d.ts +3 -0
  25. package/lib/ed448.js +86 -83
  26. package/lib/esm/abstract/bls.js +75 -74
  27. package/lib/esm/abstract/{group.js → curve.js} +31 -1
  28. package/lib/esm/abstract/edwards.js +204 -387
  29. package/lib/esm/abstract/hash-to-curve.js +38 -11
  30. package/lib/esm/abstract/modular.js +69 -47
  31. package/lib/esm/abstract/montgomery.js +24 -69
  32. package/lib/esm/abstract/poseidon.js +109 -0
  33. package/lib/esm/abstract/utils.js +58 -82
  34. package/lib/esm/abstract/weierstrass.js +484 -678
  35. package/lib/esm/bls12-381.js +75 -70
  36. package/lib/esm/bn.js +1 -1
  37. package/lib/esm/ed25519.js +80 -78
  38. package/lib/esm/ed448.js +84 -82
  39. package/lib/esm/jubjub.js +1 -1
  40. package/lib/esm/p224.js +1 -1
  41. package/lib/esm/p256.js +11 -9
  42. package/lib/esm/p384.js +11 -9
  43. package/lib/esm/p521.js +12 -23
  44. package/lib/esm/secp256k1.js +124 -162
  45. package/lib/esm/stark.js +105 -41
  46. package/lib/jubjub.d.ts +2 -2
  47. package/lib/jubjub.js +1 -1
  48. package/lib/p192.d.ts +26 -48
  49. package/lib/p224.d.ts +26 -48
  50. package/lib/p224.js +1 -1
  51. package/lib/p256.d.ts +29 -48
  52. package/lib/p256.js +13 -10
  53. package/lib/p384.d.ts +29 -48
  54. package/lib/p384.js +13 -10
  55. package/lib/p521.d.ts +37 -57
  56. package/lib/p521.js +14 -24
  57. package/lib/secp256k1.d.ts +37 -46
  58. package/lib/secp256k1.js +124 -162
  59. package/lib/stark.d.ts +39 -22
  60. package/lib/stark.js +108 -41
  61. package/package.json +15 -10
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.poseidon = exports.splitConstants = exports.validateOpts = void 0;
4
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
+ // Poseidon Hash: https://eprint.iacr.org/2019/458.pdf, https://www.poseidon-hash.info
6
+ const modular_js_1 = require("./modular.js");
7
+ function validateOpts(opts) {
8
+ const { Fp } = opts;
9
+ (0, modular_js_1.validateField)(Fp);
10
+ for (const i of ['t', 'roundsFull', 'roundsPartial']) {
11
+ if (typeof opts[i] !== 'number' || !Number.isSafeInteger(opts[i]))
12
+ throw new Error(`Poseidon: invalid param ${i}=${opts[i]} (${typeof opts[i]})`);
13
+ }
14
+ if (opts.reversePartialPowIdx !== undefined && typeof opts.reversePartialPowIdx !== 'boolean')
15
+ throw new Error(`Poseidon: invalid param reversePartialPowIdx=${opts.reversePartialPowIdx}`);
16
+ // Default is 5, but by some reasons stark uses 3
17
+ let sboxPower = opts.sboxPower;
18
+ if (sboxPower === undefined)
19
+ sboxPower = 5;
20
+ if (typeof sboxPower !== 'number' || !Number.isSafeInteger(sboxPower))
21
+ throw new Error(`Poseidon wrong sboxPower=${sboxPower}`);
22
+ const _sboxPower = BigInt(sboxPower);
23
+ let sboxFn = (n) => (0, modular_js_1.FpPow)(Fp, n, _sboxPower);
24
+ // Unwrapped sbox power for common cases (195->142μs)
25
+ if (sboxPower === 3)
26
+ sboxFn = (n) => Fp.mul(Fp.sqrN(n), n);
27
+ else if (sboxPower === 5)
28
+ sboxFn = (n) => Fp.mul(Fp.sqrN(Fp.sqrN(n)), n);
29
+ if (opts.roundsFull % 2 !== 0)
30
+ throw new Error(`Poseidon roundsFull is not even: ${opts.roundsFull}`);
31
+ const rounds = opts.roundsFull + opts.roundsPartial;
32
+ if (!Array.isArray(opts.roundConstants) || opts.roundConstants.length !== rounds)
33
+ throw new Error('Poseidon: wrong round constants');
34
+ const roundConstants = opts.roundConstants.map((rc) => {
35
+ if (!Array.isArray(rc) || rc.length !== opts.t)
36
+ throw new Error(`Poseidon wrong round constants: ${rc}`);
37
+ return rc.map((i) => {
38
+ if (typeof i !== 'bigint' || !Fp.isValid(i))
39
+ throw new Error(`Poseidon wrong round constant=${i}`);
40
+ return Fp.create(i);
41
+ });
42
+ });
43
+ // MDS is TxT matrix
44
+ if (!Array.isArray(opts.mds) || opts.mds.length !== opts.t)
45
+ throw new Error('Poseidon: wrong MDS matrix');
46
+ const mds = opts.mds.map((mdsRow) => {
47
+ if (!Array.isArray(mdsRow) || mdsRow.length !== opts.t)
48
+ throw new Error(`Poseidon MDS matrix row: ${mdsRow}`);
49
+ return mdsRow.map((i) => {
50
+ if (typeof i !== 'bigint')
51
+ throw new Error(`Poseidon MDS matrix value=${i}`);
52
+ return Fp.create(i);
53
+ });
54
+ });
55
+ return Object.freeze({ ...opts, rounds, sboxFn, roundConstants, mds });
56
+ }
57
+ exports.validateOpts = validateOpts;
58
+ function splitConstants(rc, t) {
59
+ if (typeof t !== 'number')
60
+ throw new Error('poseidonSplitConstants: wrong t');
61
+ if (!Array.isArray(rc) || rc.length % t)
62
+ throw new Error('poseidonSplitConstants: wrong rc');
63
+ const res = [];
64
+ let tmp = [];
65
+ for (let i = 0; i < rc.length; i++) {
66
+ tmp.push(rc[i]);
67
+ if (tmp.length === t) {
68
+ res.push(tmp);
69
+ tmp = [];
70
+ }
71
+ }
72
+ return res;
73
+ }
74
+ exports.splitConstants = splitConstants;
75
+ function poseidon(opts) {
76
+ const { t, Fp, rounds, sboxFn, reversePartialPowIdx } = validateOpts(opts);
77
+ const halfRoundsFull = Math.floor(opts.roundsFull / 2);
78
+ const partialIdx = reversePartialPowIdx ? t - 1 : 0;
79
+ const poseidonRound = (values, isFull, idx) => {
80
+ values = values.map((i, j) => Fp.add(i, opts.roundConstants[idx][j]));
81
+ if (isFull)
82
+ values = values.map((i) => sboxFn(i));
83
+ else
84
+ values[partialIdx] = sboxFn(values[partialIdx]);
85
+ // Matrix multiplication
86
+ values = opts.mds.map((i) => i.reduce((acc, i, j) => Fp.add(acc, Fp.mulN(i, values[j])), Fp.ZERO));
87
+ return values;
88
+ };
89
+ const poseidonHash = function poseidonHash(values) {
90
+ if (!Array.isArray(values) || values.length !== t)
91
+ throw new Error(`Poseidon: wrong values (expected array of bigints with length ${t})`);
92
+ values = values.map((i) => {
93
+ if (typeof i !== 'bigint')
94
+ throw new Error(`Poseidon: wrong value=${i} (${typeof i})`);
95
+ return Fp.create(i);
96
+ });
97
+ let round = 0;
98
+ // Apply r_f/2 full rounds.
99
+ for (let i = 0; i < halfRoundsFull; i++)
100
+ values = poseidonRound(values, true, round++);
101
+ // Apply r_p partial rounds.
102
+ for (let i = 0; i < opts.roundsPartial; i++)
103
+ values = poseidonRound(values, false, round++);
104
+ // Apply r_f/2 full rounds.
105
+ for (let i = 0; i < halfRoundsFull; i++)
106
+ values = poseidonRound(values, true, round++);
107
+ if (round !== rounds)
108
+ throw new Error(`Poseidon: wrong number of rounds: last round=${round}, total=${rounds}`);
109
+ return values;
110
+ };
111
+ // For verification in tests
112
+ poseidonHash.roundConstants = opts.roundConstants;
113
+ return poseidonHash;
114
+ }
115
+ exports.poseidon = poseidon;
@@ -1,7 +1,5 @@
1
- /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
- import * as mod from './modular.js';
3
1
  export declare type Hex = Uint8Array | string;
4
- export declare type PrivKey = Hex | bigint | number;
2
+ export declare type PrivKey = Hex | bigint;
5
3
  export declare type CHash = {
6
4
  (message: Uint8Array | string): Uint8Array;
7
5
  blockLen: number;
@@ -10,49 +8,23 @@ export declare type CHash = {
10
8
  dkLen?: number;
11
9
  }): any;
12
10
  };
13
- export declare type BasicCurve<T> = {
14
- Fp: mod.Field<T>;
15
- n: bigint;
16
- nBitLength?: number;
17
- nByteLength?: number;
18
- h: bigint;
19
- hEff?: bigint;
20
- Gx: T;
21
- Gy: T;
22
- wrapPrivateKey?: boolean;
23
- allowInfinityPoint?: boolean;
24
- };
25
- export declare function isPositiveInt(num: any): num is number;
26
- export declare function validateOpts<FP, T>(curve: BasicCurve<FP> & T): Readonly<{
27
- readonly nBitLength: number;
28
- readonly nByteLength: number;
29
- } & BasicCurve<FP> & T>;
30
- export declare function bytesToHex(uint8a: Uint8Array): string;
11
+ export declare type FHash = (message: Uint8Array | string) => Uint8Array;
12
+ export declare function bytesToHex(bytes: Uint8Array): string;
31
13
  export declare function numberToHexUnpadded(num: number | bigint): string;
32
14
  export declare function hexToNumber(hex: string): bigint;
33
15
  export declare function hexToBytes(hex: string): Uint8Array;
34
16
  export declare function bytesToNumberBE(bytes: Uint8Array): bigint;
35
- export declare function bytesToNumberLE(uint8a: Uint8Array): bigint;
17
+ export declare function bytesToNumberLE(bytes: Uint8Array): bigint;
36
18
  export declare const numberToBytesBE: (n: bigint, len: number) => Uint8Array;
37
19
  export declare const numberToBytesLE: (n: bigint, len: number) => Uint8Array;
20
+ export declare const numberToVarBytesBE: (n: bigint) => Uint8Array;
38
21
  export declare function ensureBytes(hex: Hex, expectedLength?: number): Uint8Array;
39
- export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
40
- export declare function nLength(n: bigint, nBitLength?: number): {
41
- nBitLength: number;
42
- nByteLength: number;
43
- };
44
- /**
45
- * FIPS 186 B.4.1-compliant "constant-time" private key generation utility.
46
- * Can take (n+8) or more bytes of uniform input e.g. from CSPRNG or KDF
47
- * and convert them into private scalar, with the modulo bias being neglible.
48
- * Needs at least 40 bytes of input for 32-byte private key.
49
- * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
50
- * @param hash hash output from SHA3 or a similar function
51
- * @returns valid private scalar
52
- */
53
- export declare function hashToPrivateScalar(hash: Hex, groupOrder: bigint, isLE?: boolean): bigint;
22
+ export declare function concatBytes(...arrs: Uint8Array[]): Uint8Array;
54
23
  export declare function equalBytes(b1: Uint8Array, b2: Uint8Array): boolean;
55
24
  export declare function bitLen(n: bigint): number;
56
25
  export declare const bitGet: (n: bigint, pos: number) => bigint;
57
26
  export declare const bitSet: (n: bigint, pos: number, value: boolean) => bigint;
58
27
  export declare const bitMask: (n: number) => bigint;
28
+ declare type ValMap = Record<string, string>;
29
+ export declare function validateObject(object: object, validators: ValMap, optValidators?: ValMap): object;
30
+ export {};
@@ -1,46 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.bitMask = exports.bitSet = exports.bitGet = exports.bitLen = exports.equalBytes = exports.hashToPrivateScalar = exports.nLength = exports.concatBytes = exports.ensureBytes = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = exports.validateOpts = exports.isPositiveInt = void 0;
3
+ exports.validateObject = exports.bitMask = exports.bitSet = exports.bitGet = exports.bitLen = exports.equalBytes = exports.concatBytes = exports.ensureBytes = exports.numberToVarBytesBE = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = void 0;
4
4
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
- const mod = require("./modular.js");
6
5
  const _0n = BigInt(0);
7
6
  const _1n = BigInt(1);
8
7
  const _2n = BigInt(2);
9
- // Bans floats and integers above 2^53-1
10
- function isPositiveInt(num) {
11
- return typeof num === 'number' && Number.isSafeInteger(num) && num > 0;
12
- }
13
- exports.isPositiveInt = isPositiveInt;
14
- function validateOpts(curve) {
15
- mod.validateField(curve.Fp);
16
- for (const i of ['n', 'h']) {
17
- const val = curve[i];
18
- if (typeof val !== 'bigint')
19
- throw new Error(`Invalid curve param ${i}=${val} (${typeof val})`);
20
- }
21
- if (!curve.Fp.isValid(curve.Gx))
22
- throw new Error('Invalid generator X coordinate Fp element');
23
- if (!curve.Fp.isValid(curve.Gy))
24
- throw new Error('Invalid generator Y coordinate Fp element');
25
- for (const i of ['nBitLength', 'nByteLength']) {
26
- const val = curve[i];
27
- if (val === undefined)
28
- continue; // Optional
29
- if (!isPositiveInt(val))
30
- throw new Error(`Invalid curve param ${i}=${val} (${typeof val})`);
31
- }
32
- // Set defaults
33
- return Object.freeze({ ...nLength(curve.n, curve.nBitLength), ...curve });
34
- }
35
- exports.validateOpts = validateOpts;
8
+ const u8a = (a) => a instanceof Uint8Array;
36
9
  const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
37
- function bytesToHex(uint8a) {
38
- if (!(uint8a instanceof Uint8Array))
39
- throw new Error('Expected Uint8Array');
10
+ function bytesToHex(bytes) {
11
+ if (!u8a(bytes))
12
+ throw new Error('Uint8Array expected');
40
13
  // pre-caching improves the speed 6x
41
14
  let hex = '';
42
- for (let i = 0; i < uint8a.length; i++) {
43
- hex += hexes[uint8a[i]];
15
+ for (let i = 0; i < bytes.length; i++) {
16
+ hex += hexes[bytes[i]];
44
17
  }
45
18
  return hex;
46
19
  }
@@ -51,27 +24,25 @@ function numberToHexUnpadded(num) {
51
24
  }
52
25
  exports.numberToHexUnpadded = numberToHexUnpadded;
53
26
  function hexToNumber(hex) {
54
- if (typeof hex !== 'string') {
55
- throw new TypeError('hexToNumber: expected string, got ' + typeof hex);
56
- }
27
+ if (typeof hex !== 'string')
28
+ throw new Error('string expected, got ' + typeof hex);
57
29
  // Big Endian
58
30
  return BigInt(`0x${hex}`);
59
31
  }
60
32
  exports.hexToNumber = hexToNumber;
61
33
  // Caching slows it down 2-3x
62
34
  function hexToBytes(hex) {
63
- if (typeof hex !== 'string') {
64
- throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
65
- }
35
+ if (typeof hex !== 'string')
36
+ throw new Error('string expected, got ' + typeof hex);
66
37
  if (hex.length % 2)
67
- throw new Error('hexToBytes: received invalid unpadded hex ' + hex.length);
38
+ throw new Error('hex string is invalid: unpadded ' + hex.length);
68
39
  const array = new Uint8Array(hex.length / 2);
69
40
  for (let i = 0; i < array.length; i++) {
70
41
  const j = i * 2;
71
42
  const hexByte = hex.slice(j, j + 2);
72
43
  const byte = Number.parseInt(hexByte, 16);
73
44
  if (Number.isNaN(byte) || byte < 0)
74
- throw new Error('Invalid byte sequence');
45
+ throw new Error('invalid byte sequence');
75
46
  array[i] = byte;
76
47
  }
77
48
  return array;
@@ -82,68 +53,41 @@ function bytesToNumberBE(bytes) {
82
53
  return hexToNumber(bytesToHex(bytes));
83
54
  }
84
55
  exports.bytesToNumberBE = bytesToNumberBE;
85
- function bytesToNumberLE(uint8a) {
86
- if (!(uint8a instanceof Uint8Array))
87
- throw new Error('Expected Uint8Array');
88
- return BigInt('0x' + bytesToHex(Uint8Array.from(uint8a).reverse()));
56
+ function bytesToNumberLE(bytes) {
57
+ if (!u8a(bytes))
58
+ throw new Error('Uint8Array expected');
59
+ return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
89
60
  }
90
61
  exports.bytesToNumberLE = bytesToNumberLE;
91
62
  const numberToBytesBE = (n, len) => hexToBytes(n.toString(16).padStart(len * 2, '0'));
92
63
  exports.numberToBytesBE = numberToBytesBE;
93
64
  const numberToBytesLE = (n, len) => (0, exports.numberToBytesBE)(n, len).reverse();
94
65
  exports.numberToBytesLE = numberToBytesLE;
66
+ // Returns variable number bytes (minimal bigint encoding?)
67
+ const numberToVarBytesBE = (n) => hexToBytes(numberToHexUnpadded(n));
68
+ exports.numberToVarBytesBE = numberToVarBytesBE;
95
69
  function ensureBytes(hex, expectedLength) {
96
70
  // Uint8Array.from() instead of hash.slice() because node.js Buffer
97
71
  // is instance of Uint8Array, and its slice() creates **mutable** copy
98
- const bytes = hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex);
72
+ const bytes = u8a(hex) ? Uint8Array.from(hex) : hexToBytes(hex);
99
73
  if (typeof expectedLength === 'number' && bytes.length !== expectedLength)
100
74
  throw new Error(`Expected ${expectedLength} bytes`);
101
75
  return bytes;
102
76
  }
103
77
  exports.ensureBytes = ensureBytes;
104
78
  // Copies several Uint8Arrays into one.
105
- function concatBytes(...arrays) {
106
- if (!arrays.every((b) => b instanceof Uint8Array))
107
- throw new Error('Uint8Array list expected');
108
- if (arrays.length === 1)
109
- return arrays[0];
110
- const length = arrays.reduce((a, arr) => a + arr.length, 0);
111
- const result = new Uint8Array(length);
112
- for (let i = 0, pad = 0; i < arrays.length; i++) {
113
- const arr = arrays[i];
114
- result.set(arr, pad);
115
- pad += arr.length;
116
- }
117
- return result;
79
+ function concatBytes(...arrs) {
80
+ const r = new Uint8Array(arrs.reduce((sum, a) => sum + a.length, 0));
81
+ let pad = 0; // walk through each item, ensure they have proper type
82
+ arrs.forEach((a) => {
83
+ if (!u8a(a))
84
+ throw new Error('Uint8Array expected');
85
+ r.set(a, pad);
86
+ pad += a.length;
87
+ });
88
+ return r;
118
89
  }
119
90
  exports.concatBytes = concatBytes;
120
- // CURVE.n lengths
121
- function nLength(n, nBitLength) {
122
- // Bit size, byte size of CURVE.n
123
- const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
124
- const nByteLength = Math.ceil(_nBitLength / 8);
125
- return { nBitLength: _nBitLength, nByteLength };
126
- }
127
- exports.nLength = nLength;
128
- /**
129
- * FIPS 186 B.4.1-compliant "constant-time" private key generation utility.
130
- * Can take (n+8) or more bytes of uniform input e.g. from CSPRNG or KDF
131
- * and convert them into private scalar, with the modulo bias being neglible.
132
- * Needs at least 40 bytes of input for 32-byte private key.
133
- * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
134
- * @param hash hash output from SHA3 or a similar function
135
- * @returns valid private scalar
136
- */
137
- function hashToPrivateScalar(hash, groupOrder, isLE = false) {
138
- hash = ensureBytes(hash);
139
- const hashLen = hash.length;
140
- const minLen = nLength(groupOrder).nByteLength + 8;
141
- if (minLen < 24 || hashLen < minLen || hashLen > 1024)
142
- throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);
143
- const num = isLE ? bytesToNumberLE(hash) : bytesToNumberBE(hash);
144
- return mod.mod(num, groupOrder - _1n) + _1n;
145
- }
146
- exports.hashToPrivateScalar = hashToPrivateScalar;
147
91
  function equalBytes(b1, b2) {
148
92
  // We don't care about timing attacks here
149
93
  if (b1.length !== b2.length)
@@ -174,3 +118,33 @@ exports.bitSet = bitSet;
174
118
  // Not using ** operator with bigints for old engines.
175
119
  const bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
176
120
  exports.bitMask = bitMask;
121
+ function validateObject(object, validators, optValidators = {}) {
122
+ const validatorFns = {
123
+ bigint: (val) => typeof val === 'bigint',
124
+ function: (val) => typeof val === 'function',
125
+ boolean: (val) => typeof val === 'boolean',
126
+ string: (val) => typeof val === 'string',
127
+ isSafeInteger: (val) => Number.isSafeInteger(val),
128
+ array: (val) => Array.isArray(val),
129
+ field: (val) => object.Fp.isValid(val),
130
+ hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
131
+ };
132
+ // type Key = keyof typeof validators;
133
+ const checkField = (fieldName, type, isOptional) => {
134
+ const checkVal = validatorFns[type];
135
+ if (typeof checkVal !== 'function')
136
+ throw new Error(`Invalid validator "${type}", expected function`);
137
+ const val = object[fieldName];
138
+ if (isOptional && val === undefined)
139
+ return;
140
+ if (!checkVal(val)) {
141
+ throw new Error(`Invalid param ${fieldName}=${val} (${typeof val}), expected ${type}`);
142
+ }
143
+ };
144
+ for (let [fieldName, type] of Object.entries(validators))
145
+ checkField(fieldName, type, false);
146
+ for (let [fieldName, type] of Object.entries(optValidators))
147
+ checkField(fieldName, type, true);
148
+ return object;
149
+ }
150
+ exports.validateObject = validateObject;
@@ -1,9 +1,9 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
2
  import * as mod from './modular.js';
3
3
  import * as ut from './utils.js';
4
- import { Hex, PrivKey } from './utils.js';
5
- import { htfOpts } from './hash-to-curve.js';
6
- import { Group, GroupConstructor } from './group.js';
4
+ import { CHash, Hex, PrivKey } from './utils.js';
5
+ import { Group, GroupConstructor, BasicCurve, AffinePoint } from './curve.js';
6
+ export type { AffinePoint };
7
7
  declare type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
8
8
  declare type EndomorphismOpts = {
9
9
  beta: bigint;
@@ -14,24 +14,24 @@ declare type EndomorphismOpts = {
14
14
  k2: bigint;
15
15
  };
16
16
  };
17
- export declare type BasicCurve<T> = ut.BasicCurve<T> & {
17
+ export declare type BasicWCurve<T> = BasicCurve<T> & {
18
18
  a: T;
19
19
  b: T;
20
- normalizePrivateKey?: (key: PrivKey) => PrivKey;
20
+ allowedPrivateKeyLengths?: readonly number[];
21
21
  wrapPrivateKey?: boolean;
22
22
  endo?: EndomorphismOpts;
23
- isTorsionFree?: (c: ProjectiveConstructor<T>, point: ProjectivePointType<T>) => boolean;
24
- clearCofactor?: (c: ProjectiveConstructor<T>, point: ProjectivePointType<T>) => ProjectivePointType<T>;
25
- htfDefaults?: htfOpts;
26
- mapToCurve?: (scalar: bigint[]) => {
27
- x: T;
28
- y: T;
29
- };
23
+ isTorsionFree?: (c: ProjConstructor<T>, point: ProjPointType<T>) => boolean;
24
+ clearCofactor?: (c: ProjConstructor<T>, point: ProjPointType<T>) => ProjPointType<T>;
30
25
  };
31
26
  declare type Entropy = Hex | true;
32
27
  export declare type SignOpts = {
33
28
  lowS?: boolean;
34
29
  extraEntropy?: Entropy;
30
+ prehash?: boolean;
31
+ };
32
+ export declare type VerOpts = {
33
+ lowS?: boolean;
34
+ prehash?: boolean;
35
35
  };
36
36
  /**
37
37
  * ### Design rationale for types
@@ -54,54 +54,41 @@ export declare type SignOpts = {
54
54
  *
55
55
  * TODO: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
56
56
  */
57
- export interface ProjectivePointType<T> extends Group<ProjectivePointType<T>> {
58
- readonly x: T;
59
- readonly y: T;
60
- readonly z: T;
61
- multiply(scalar: number | bigint, affinePoint?: PointType<T>): ProjectivePointType<T>;
62
- multiplyUnsafe(scalar: bigint): ProjectivePointType<T>;
63
- toAffine(invZ?: T): PointType<T>;
64
- }
65
- export interface ProjectiveConstructor<T> extends GroupConstructor<ProjectivePointType<T>> {
66
- new (x: T, y: T, z: T): ProjectivePointType<T>;
67
- fromAffine(p: PointType<T>): ProjectivePointType<T>;
68
- toAffineBatch(points: ProjectivePointType<T>[]): PointType<T>[];
69
- normalizeZ(points: ProjectivePointType<T>[]): ProjectivePointType<T>[];
70
- }
71
- export interface PointType<T> extends Group<PointType<T>> {
72
- readonly x: T;
73
- readonly y: T;
57
+ export interface ProjPointType<T> extends Group<ProjPointType<T>> {
58
+ readonly px: T;
59
+ readonly py: T;
60
+ readonly pz: T;
61
+ multiply(scalar: bigint): ProjPointType<T>;
62
+ multiplyUnsafe(scalar: bigint): ProjPointType<T>;
63
+ multiplyAndAddUnsafe(Q: ProjPointType<T>, a: bigint, b: bigint): ProjPointType<T> | undefined;
74
64
  _setWindowSize(windowSize: number): void;
65
+ toAffine(iz?: T): AffinePoint<T>;
66
+ isTorsionFree(): boolean;
67
+ clearCofactor(): ProjPointType<T>;
68
+ assertValidity(): void;
75
69
  hasEvenY(): boolean;
76
70
  toRawBytes(isCompressed?: boolean): Uint8Array;
77
71
  toHex(isCompressed?: boolean): string;
78
- assertValidity(): void;
79
- multiplyAndAddUnsafe(Q: PointType<T>, a: bigint, b: bigint): PointType<T> | undefined;
80
72
  }
81
- export interface PointConstructor<T> extends GroupConstructor<PointType<T>> {
82
- new (x: T, y: T): PointType<T>;
83
- fromHex(hex: Hex): PointType<T>;
84
- fromPrivateKey(privateKey: PrivKey): PointType<T>;
85
- hashToCurve(msg: Hex, options?: Partial<htfOpts>): PointType<T>;
86
- encodeToCurve(msg: Hex, options?: Partial<htfOpts>): PointType<T>;
73
+ export interface ProjConstructor<T> extends GroupConstructor<ProjPointType<T>> {
74
+ new (x: T, y: T, z: T): ProjPointType<T>;
75
+ fromAffine(p: AffinePoint<T>): ProjPointType<T>;
76
+ fromHex(hex: Hex): ProjPointType<T>;
77
+ fromPrivateKey(privateKey: PrivKey): ProjPointType<T>;
78
+ normalizeZ(points: ProjPointType<T>[]): ProjPointType<T>[];
87
79
  }
88
- export declare type CurvePointsType<T> = BasicCurve<T> & {
89
- fromBytes: (bytes: Uint8Array) => {
90
- x: T;
91
- y: T;
92
- };
93
- toBytes: (c: PointConstructor<T>, point: PointType<T>, compressed: boolean) => Uint8Array;
80
+ export declare type CurvePointsType<T> = BasicWCurve<T> & {
81
+ fromBytes: (bytes: Uint8Array) => AffinePoint<T>;
82
+ toBytes: (c: ProjConstructor<T>, point: ProjPointType<T>, compressed: boolean) => Uint8Array;
94
83
  };
95
84
  export declare type CurvePointsRes<T> = {
96
- Point: PointConstructor<T>;
97
- ProjectivePoint: ProjectiveConstructor<T>;
85
+ ProjectivePoint: ProjConstructor<T>;
98
86
  normalizePrivateKey: (key: PrivKey) => bigint;
99
87
  weierstrassEquation: (x: T) => T;
100
88
  isWithinCurveOrder: (num: bigint) => boolean;
101
89
  };
102
90
  export declare function weierstrassPoints<T>(opts: CurvePointsType<T>): {
103
- Point: PointConstructor<T>;
104
- ProjectivePoint: ProjectiveConstructor<T>;
91
+ ProjectivePoint: ProjConstructor<T>;
105
92
  normalizePrivateKey: (key: PrivKey) => bigint;
106
93
  weierstrassEquation: (x: T) => T;
107
94
  isWithinCurveOrder: (num: bigint) => boolean;
@@ -111,27 +98,32 @@ export interface SignatureType {
111
98
  readonly s: bigint;
112
99
  readonly recovery?: number;
113
100
  assertValidity(): void;
114
- copyWithRecoveryBit(recovery: number): SignatureType;
101
+ addRecoveryBit(recovery: number): SignatureType;
115
102
  hasHighS(): boolean;
116
103
  normalizeS(): SignatureType;
117
- recoverPublicKey(msgHash: Hex): PointType<bigint>;
118
- toDERRawBytes(isCompressed?: boolean): Uint8Array;
119
- toDERHex(isCompressed?: boolean): string;
104
+ recoverPublicKey(msgHash: Hex): ProjPointType<bigint>;
120
105
  toCompactRawBytes(): Uint8Array;
121
106
  toCompactHex(): string;
107
+ toDERRawBytes(isCompressed?: boolean): Uint8Array;
108
+ toDERHex(isCompressed?: boolean): string;
122
109
  }
123
110
  export declare type SignatureConstructor = {
124
111
  new (r: bigint, s: bigint): SignatureType;
125
112
  fromCompact(hex: Hex): SignatureType;
126
113
  fromDER(hex: Hex): SignatureType;
127
114
  };
128
- export declare type PubKey = Hex | PointType<bigint>;
129
- export declare type CurveType = BasicCurve<bigint> & {
130
- lowS?: boolean;
131
- hash: ut.CHash;
115
+ declare type SignatureLike = {
116
+ r: bigint;
117
+ s: bigint;
118
+ };
119
+ export declare type PubKey = Hex | ProjPointType<bigint>;
120
+ export declare type CurveType = BasicWCurve<bigint> & {
121
+ hash: CHash;
132
122
  hmac: HmacFnSync;
133
123
  randomBytes: (bytesLength?: number) => Uint8Array;
134
- truncateHash?: (hash: Uint8Array, truncateOnly?: boolean) => bigint;
124
+ lowS?: boolean;
125
+ bits2int?: (bytes: Uint8Array) => bigint;
126
+ bits2int_modN?: (bytes: Uint8Array) => bigint;
135
127
  };
136
128
  declare function validateOpts(curve: CurveType): Readonly<{
137
129
  readonly nBitLength: number;
@@ -142,45 +134,31 @@ declare function validateOpts(curve: CurveType): Readonly<{
142
134
  readonly hEff?: bigint | undefined;
143
135
  readonly Gx: bigint;
144
136
  readonly Gy: bigint;
145
- readonly wrapPrivateKey?: boolean | undefined;
146
137
  readonly allowInfinityPoint?: boolean | undefined;
147
138
  readonly a: bigint;
148
139
  readonly b: bigint;
149
- readonly normalizePrivateKey?: ((key: ut.PrivKey) => ut.PrivKey) | undefined;
140
+ readonly allowedPrivateKeyLengths?: readonly number[] | undefined;
141
+ readonly wrapPrivateKey?: boolean | undefined;
150
142
  readonly endo?: EndomorphismOpts | undefined;
151
- readonly isTorsionFree?: ((c: ProjectiveConstructor<bigint>, point: ProjectivePointType<bigint>) => boolean) | undefined;
152
- readonly clearCofactor?: ((c: ProjectiveConstructor<bigint>, point: ProjectivePointType<bigint>) => ProjectivePointType<bigint>) | undefined;
153
- readonly htfDefaults?: htfOpts | undefined;
154
- readonly mapToCurve?: ((scalar: bigint[]) => {
155
- x: bigint;
156
- y: bigint;
157
- }) | undefined;
158
- lowS: boolean;
143
+ readonly isTorsionFree?: ((c: ProjConstructor<bigint>, point: ProjPointType<bigint>) => boolean) | undefined;
144
+ readonly clearCofactor?: ((c: ProjConstructor<bigint>, point: ProjPointType<bigint>) => ProjPointType<bigint>) | undefined;
159
145
  readonly hash: ut.CHash;
160
146
  readonly hmac: HmacFnSync;
161
147
  readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
162
- readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
148
+ lowS: boolean;
149
+ readonly bits2int?: ((bytes: Uint8Array) => bigint) | undefined;
150
+ readonly bits2int_modN?: ((bytes: Uint8Array) => bigint) | undefined;
163
151
  }>;
164
152
  export declare type CurveFn = {
165
153
  CURVE: ReturnType<typeof validateOpts>;
166
154
  getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
167
- getSharedSecret: (privateA: PrivKey, publicB: PubKey, isCompressed?: boolean) => Uint8Array;
155
+ getSharedSecret: (privateA: PrivKey, publicB: Hex, isCompressed?: boolean) => Uint8Array;
168
156
  sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
169
- signUnhashed: (msg: Uint8Array, privKey: PrivKey, opts?: SignOpts) => SignatureType;
170
- verify: (signature: Hex | SignatureType, msgHash: Hex, publicKey: PubKey, opts?: {
171
- lowS?: boolean;
172
- }) => boolean;
173
- Point: PointConstructor<bigint>;
174
- ProjectivePoint: ProjectiveConstructor<bigint>;
157
+ verify: (signature: Hex | SignatureLike, msgHash: Hex, publicKey: Hex, opts?: VerOpts) => boolean;
158
+ ProjectivePoint: ProjConstructor<bigint>;
175
159
  Signature: SignatureConstructor;
176
160
  utils: {
177
- _bigintToBytes: (num: bigint) => Uint8Array;
178
- _bigintToString: (num: bigint) => string;
179
161
  _normalizePrivateKey: (key: PrivKey) => bigint;
180
- _normalizePublicKey: (publicKey: PubKey) => PointType<bigint>;
181
- _isWithinCurveOrder: (num: bigint) => boolean;
182
- _isValidFieldElement: (num: bigint) => boolean;
183
- _weierstrassEquation: (x: bigint) => bigint;
184
162
  isValidPrivateKey(privateKey: PrivKey): boolean;
185
163
  hashToPrivateKey: (hash: Hex) => Uint8Array;
186
164
  randomPrivateKey: () => Uint8Array;
@@ -199,4 +177,3 @@ export declare function mapToCurveSimpleSWU<T>(Fp: mod.Field<T>, opts: {
199
177
  x: T;
200
178
  y: T;
201
179
  };
202
- export {};