@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
@@ -1,41 +1,16 @@
1
1
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
- import * as mod from './modular.js';
3
2
  const _0n = BigInt(0);
4
3
  const _1n = BigInt(1);
5
4
  const _2n = BigInt(2);
6
- // Bans floats and integers above 2^53-1
7
- export function isPositiveInt(num) {
8
- return typeof num === 'number' && Number.isSafeInteger(num) && num > 0;
9
- }
10
- export function validateOpts(curve) {
11
- mod.validateField(curve.Fp);
12
- for (const i of ['n', 'h']) {
13
- const val = curve[i];
14
- if (typeof val !== 'bigint')
15
- throw new Error(`Invalid curve param ${i}=${val} (${typeof val})`);
16
- }
17
- if (!curve.Fp.isValid(curve.Gx))
18
- throw new Error('Invalid generator X coordinate Fp element');
19
- if (!curve.Fp.isValid(curve.Gy))
20
- throw new Error('Invalid generator Y coordinate Fp element');
21
- for (const i of ['nBitLength', 'nByteLength']) {
22
- const val = curve[i];
23
- if (val === undefined)
24
- continue; // Optional
25
- if (!isPositiveInt(val))
26
- throw new Error(`Invalid curve param ${i}=${val} (${typeof val})`);
27
- }
28
- // Set defaults
29
- return Object.freeze({ ...nLength(curve.n, curve.nBitLength), ...curve });
30
- }
5
+ const u8a = (a) => a instanceof Uint8Array;
31
6
  const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
32
- export function bytesToHex(uint8a) {
33
- if (!(uint8a instanceof Uint8Array))
34
- throw new Error('Expected Uint8Array');
7
+ export function bytesToHex(bytes) {
8
+ if (!u8a(bytes))
9
+ throw new Error('Uint8Array expected');
35
10
  // pre-caching improves the speed 6x
36
11
  let hex = '';
37
- for (let i = 0; i < uint8a.length; i++) {
38
- hex += hexes[uint8a[i]];
12
+ for (let i = 0; i < bytes.length; i++) {
13
+ hex += hexes[bytes[i]];
39
14
  }
40
15
  return hex;
41
16
  }
@@ -44,26 +19,24 @@ export function numberToHexUnpadded(num) {
44
19
  return hex.length & 1 ? `0${hex}` : hex;
45
20
  }
46
21
  export function hexToNumber(hex) {
47
- if (typeof hex !== 'string') {
48
- throw new TypeError('hexToNumber: expected string, got ' + typeof hex);
49
- }
22
+ if (typeof hex !== 'string')
23
+ throw new Error('string expected, got ' + typeof hex);
50
24
  // Big Endian
51
25
  return BigInt(`0x${hex}`);
52
26
  }
53
27
  // Caching slows it down 2-3x
54
28
  export function hexToBytes(hex) {
55
- if (typeof hex !== 'string') {
56
- throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
57
- }
29
+ if (typeof hex !== 'string')
30
+ throw new Error('string expected, got ' + typeof hex);
58
31
  if (hex.length % 2)
59
- throw new Error('hexToBytes: received invalid unpadded hex ' + hex.length);
32
+ throw new Error('hex string is invalid: unpadded ' + hex.length);
60
33
  const array = new Uint8Array(hex.length / 2);
61
34
  for (let i = 0; i < array.length; i++) {
62
35
  const j = i * 2;
63
36
  const hexByte = hex.slice(j, j + 2);
64
37
  const byte = Number.parseInt(hexByte, 16);
65
38
  if (Number.isNaN(byte) || byte < 0)
66
- throw new Error('Invalid byte sequence');
39
+ throw new Error('invalid byte sequence');
67
40
  array[i] = byte;
68
41
  }
69
42
  return array;
@@ -72,60 +45,34 @@ export function hexToBytes(hex) {
72
45
  export function bytesToNumberBE(bytes) {
73
46
  return hexToNumber(bytesToHex(bytes));
74
47
  }
75
- export function bytesToNumberLE(uint8a) {
76
- if (!(uint8a instanceof Uint8Array))
77
- throw new Error('Expected Uint8Array');
78
- return BigInt('0x' + bytesToHex(Uint8Array.from(uint8a).reverse()));
48
+ export function bytesToNumberLE(bytes) {
49
+ if (!u8a(bytes))
50
+ throw new Error('Uint8Array expected');
51
+ return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
79
52
  }
80
53
  export const numberToBytesBE = (n, len) => hexToBytes(n.toString(16).padStart(len * 2, '0'));
81
54
  export const numberToBytesLE = (n, len) => numberToBytesBE(n, len).reverse();
55
+ // Returns variable number bytes (minimal bigint encoding?)
56
+ export const numberToVarBytesBE = (n) => hexToBytes(numberToHexUnpadded(n));
82
57
  export function ensureBytes(hex, expectedLength) {
83
58
  // Uint8Array.from() instead of hash.slice() because node.js Buffer
84
59
  // is instance of Uint8Array, and its slice() creates **mutable** copy
85
- const bytes = hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes(hex);
60
+ const bytes = u8a(hex) ? Uint8Array.from(hex) : hexToBytes(hex);
86
61
  if (typeof expectedLength === 'number' && bytes.length !== expectedLength)
87
62
  throw new Error(`Expected ${expectedLength} bytes`);
88
63
  return bytes;
89
64
  }
90
65
  // Copies several Uint8Arrays into one.
91
- export function concatBytes(...arrays) {
92
- if (!arrays.every((b) => b instanceof Uint8Array))
93
- throw new Error('Uint8Array list expected');
94
- if (arrays.length === 1)
95
- return arrays[0];
96
- const length = arrays.reduce((a, arr) => a + arr.length, 0);
97
- const result = new Uint8Array(length);
98
- for (let i = 0, pad = 0; i < arrays.length; i++) {
99
- const arr = arrays[i];
100
- result.set(arr, pad);
101
- pad += arr.length;
102
- }
103
- return result;
104
- }
105
- // CURVE.n lengths
106
- export function nLength(n, nBitLength) {
107
- // Bit size, byte size of CURVE.n
108
- const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
109
- const nByteLength = Math.ceil(_nBitLength / 8);
110
- return { nBitLength: _nBitLength, nByteLength };
111
- }
112
- /**
113
- * FIPS 186 B.4.1-compliant "constant-time" private key generation utility.
114
- * Can take (n+8) or more bytes of uniform input e.g. from CSPRNG or KDF
115
- * and convert them into private scalar, with the modulo bias being neglible.
116
- * Needs at least 40 bytes of input for 32-byte private key.
117
- * https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/
118
- * @param hash hash output from SHA3 or a similar function
119
- * @returns valid private scalar
120
- */
121
- export function hashToPrivateScalar(hash, groupOrder, isLE = false) {
122
- hash = ensureBytes(hash);
123
- const hashLen = hash.length;
124
- const minLen = nLength(groupOrder).nByteLength + 8;
125
- if (minLen < 24 || hashLen < minLen || hashLen > 1024)
126
- throw new Error(`hashToPrivateScalar: expected ${minLen}-1024 bytes of input, got ${hashLen}`);
127
- const num = isLE ? bytesToNumberLE(hash) : bytesToNumberBE(hash);
128
- return mod.mod(num, groupOrder - _1n) + _1n;
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;
129
76
  }
130
77
  export function equalBytes(b1, b2) {
131
78
  // We don't care about timing attacks here
@@ -152,3 +99,32 @@ export const bitSet = (n, pos, value) => n | ((value ? _1n : _0n) << BigInt(pos)
152
99
  // Return mask for N bits (Same as BigInt(`0b${Array(i).fill('1').join('')}`))
153
100
  // Not using ** operator with bigints for old engines.
154
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
+ }