@noble/curves 2.0.0-beta.1 → 2.0.0-beta.3

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 (96) hide show
  1. package/README.md +443 -276
  2. package/abstract/bls.d.ts +17 -17
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js.map +1 -1
  5. package/abstract/curve.d.ts +14 -9
  6. package/abstract/curve.d.ts.map +1 -1
  7. package/abstract/curve.js +9 -3
  8. package/abstract/curve.js.map +1 -1
  9. package/abstract/edwards.d.ts +7 -9
  10. package/abstract/edwards.d.ts.map +1 -1
  11. package/abstract/edwards.js +12 -16
  12. package/abstract/edwards.js.map +1 -1
  13. package/abstract/hash-to-curve.d.ts +32 -31
  14. package/abstract/hash-to-curve.d.ts.map +1 -1
  15. package/abstract/hash-to-curve.js +15 -14
  16. package/abstract/hash-to-curve.js.map +1 -1
  17. package/abstract/modular.d.ts.map +1 -1
  18. package/abstract/modular.js +7 -5
  19. package/abstract/modular.js.map +1 -1
  20. package/abstract/montgomery.d.ts +3 -3
  21. package/abstract/montgomery.d.ts.map +1 -1
  22. package/abstract/montgomery.js +9 -13
  23. package/abstract/montgomery.js.map +1 -1
  24. package/abstract/oprf.d.ts +4 -4
  25. package/abstract/oprf.d.ts.map +1 -1
  26. package/abstract/oprf.js +3 -3
  27. package/abstract/oprf.js.map +1 -1
  28. package/abstract/poseidon.d.ts.map +1 -1
  29. package/abstract/poseidon.js +8 -9
  30. package/abstract/poseidon.js.map +1 -1
  31. package/abstract/utils.d.ts +74 -1
  32. package/abstract/utils.d.ts.map +1 -1
  33. package/abstract/utils.js +67 -17
  34. package/abstract/utils.js.map +1 -1
  35. package/abstract/weierstrass.d.ts +66 -20
  36. package/abstract/weierstrass.d.ts.map +1 -1
  37. package/abstract/weierstrass.js +72 -68
  38. package/abstract/weierstrass.js.map +1 -1
  39. package/bls12-381.d.ts +3 -9
  40. package/bls12-381.d.ts.map +1 -1
  41. package/bls12-381.js +3 -14
  42. package/bls12-381.js.map +1 -1
  43. package/bn254.d.ts +4 -4
  44. package/bn254.d.ts.map +1 -1
  45. package/bn254.js +1 -1
  46. package/bn254.js.map +1 -1
  47. package/ed25519.d.ts +22 -18
  48. package/ed25519.d.ts.map +1 -1
  49. package/ed25519.js +59 -31
  50. package/ed25519.js.map +1 -1
  51. package/ed448.d.ts +17 -8
  52. package/ed448.d.ts.map +1 -1
  53. package/ed448.js +69 -52
  54. package/ed448.js.map +1 -1
  55. package/index.d.ts +1 -0
  56. package/index.js +20 -4
  57. package/index.js.map +1 -1
  58. package/misc.d.ts.map +1 -1
  59. package/misc.js +6 -8
  60. package/misc.js.map +1 -1
  61. package/nist.d.ts +20 -2
  62. package/nist.d.ts.map +1 -1
  63. package/nist.js +30 -10
  64. package/nist.js.map +1 -1
  65. package/package.json +34 -37
  66. package/secp256k1.d.ts +10 -7
  67. package/secp256k1.d.ts.map +1 -1
  68. package/secp256k1.js +15 -16
  69. package/secp256k1.js.map +1 -1
  70. package/src/abstract/bls.ts +22 -22
  71. package/src/abstract/curve.ts +19 -5
  72. package/src/abstract/edwards.ts +20 -23
  73. package/src/abstract/hash-to-curve.ts +50 -51
  74. package/src/abstract/modular.ts +7 -5
  75. package/src/abstract/montgomery.ts +12 -18
  76. package/src/abstract/oprf.ts +6 -6
  77. package/src/abstract/poseidon.ts +6 -8
  78. package/src/abstract/weierstrass.ts +139 -89
  79. package/src/bls12-381.ts +4 -15
  80. package/src/bn254.ts +7 -7
  81. package/src/ed25519.ts +65 -40
  82. package/src/ed448.ts +87 -69
  83. package/src/index.ts +19 -3
  84. package/src/misc.ts +7 -8
  85. package/src/nist.ts +31 -15
  86. package/src/secp256k1.ts +16 -18
  87. package/src/utils.ts +33 -83
  88. package/src/webcrypto.ts +148 -107
  89. package/utils.d.ts +5 -21
  90. package/utils.d.ts.map +1 -1
  91. package/utils.js +31 -74
  92. package/utils.js.map +1 -1
  93. package/webcrypto.d.ts +73 -21
  94. package/webcrypto.d.ts.map +1 -1
  95. package/webcrypto.js +101 -76
  96. package/webcrypto.js.map +1 -1
@@ -7,18 +7,18 @@
7
7
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8
8
  import type { CHash } from '../utils.ts';
9
9
  import {
10
- _validateObject,
11
10
  abytes,
11
+ asafenumber,
12
12
  asciiToBytes,
13
13
  bytesToNumberBE,
14
14
  concatBytes,
15
15
  isBytes,
16
- isHash,
16
+ validateObject,
17
17
  } from '../utils.ts';
18
18
  import type { AffinePoint, PC_ANY, PC_F, PC_P } from './curve.ts';
19
19
  import { FpInvertBatch, mod, type IField } from './modular.ts';
20
20
 
21
- export type UnicodeOrBytes = string | Uint8Array;
21
+ export type AsciiOrBytes = string | Uint8Array;
22
22
 
23
23
  /**
24
24
  * * `DST` is a domain separation tag, defined in section 2.2.5
@@ -29,7 +29,7 @@ export type UnicodeOrBytes = string | Uint8Array;
29
29
  * * `hash` conforming to `utils.CHash` interface, with `outputLen` / `blockLen` props
30
30
  */
31
31
  export type H2COpts = {
32
- DST: UnicodeOrBytes;
32
+ DST: AsciiOrBytes;
33
33
  expand: 'xmd' | 'xof';
34
34
  hash: CHash;
35
35
  p: bigint;
@@ -40,14 +40,37 @@ export type H2CHashOpts = {
40
40
  expand: 'xmd' | 'xof';
41
41
  hash: CHash;
42
42
  };
43
+ export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
44
+
45
+ // Separated from initialization opts, so users won't accidentally change per-curve parameters
46
+ // (changing DST is ok!)
47
+ export type H2CDSTOpts = { DST: AsciiOrBytes };
48
+ export type H2CHasherBase<PC extends PC_ANY> = {
49
+ hashToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC>;
50
+ hashToScalar(msg: Uint8Array, options?: H2CDSTOpts): bigint;
51
+ deriveToCurve?(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC>;
52
+ Point: PC;
53
+ };
54
+ /**
55
+ * RFC 9380 methods, with cofactor clearing. See https://www.rfc-editor.org/rfc/rfc9380#section-3.
56
+ *
57
+ * * hashToCurve: `map(hash(input))`, encodes RANDOM bytes to curve (WITH hashing)
58
+ * * encodeToCurve: `map(hash(input))`, encodes NON-UNIFORM bytes to curve (WITH hashing)
59
+ * * mapToCurve: `map(scalars)`, encodes NON-UNIFORM scalars to curve (NO hashing)
60
+ */
61
+ export type H2CHasher<PC extends PC_ANY> = H2CHasherBase<PC> & {
62
+ encodeToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC>;
63
+ mapToCurve: MapToCurve<PC_F<PC>>;
64
+ defaults: H2COpts & { encodeDST?: AsciiOrBytes };
65
+ };
43
66
 
44
67
  // Octet Stream to Integer. "spec" implementation of os2ip is 2.5x slower vs bytesToNumberBE.
45
68
  const os2ip = bytesToNumberBE;
46
69
 
47
70
  // Integer to Octet Stream (numberToBytesBE)
48
71
  function i2osp(value: number, length: number): Uint8Array {
49
- anum(value);
50
- anum(length);
72
+ asafenumber(value);
73
+ asafenumber(length);
51
74
  if (value < 0 || value >= 1 << (8 * length)) throw new Error('invalid I2OSP input: ' + value);
52
75
  const res = Array.from({ length }).fill(0) as number[];
53
76
  for (let i = length - 1; i >= 0; i--) {
@@ -65,13 +88,9 @@ function strxor(a: Uint8Array, b: Uint8Array): Uint8Array {
65
88
  return arr;
66
89
  }
67
90
 
68
- function anum(item: unknown): void {
69
- if (!Number.isSafeInteger(item)) throw new Error('number expected');
70
- }
71
-
72
91
  // User can always use utf8 if they want, by passing Uint8Array.
73
92
  // If string is passed, we treat it as ASCII: other formats are likely a mistake.
74
- function normDST(DST: UnicodeOrBytes): Uint8Array {
93
+ function normDST(DST: AsciiOrBytes): Uint8Array {
75
94
  if (!isBytes(DST) && typeof DST !== 'string')
76
95
  throw new Error('DST must be Uint8Array or ascii string');
77
96
  return typeof DST === 'string' ? asciiToBytes(DST) : DST;
@@ -83,12 +102,12 @@ function normDST(DST: UnicodeOrBytes): Uint8Array {
83
102
  */
84
103
  export function expand_message_xmd(
85
104
  msg: Uint8Array,
86
- DST: UnicodeOrBytes,
105
+ DST: AsciiOrBytes,
87
106
  lenInBytes: number,
88
107
  H: CHash
89
108
  ): Uint8Array {
90
109
  abytes(msg);
91
- anum(lenInBytes);
110
+ asafenumber(lenInBytes);
92
111
  DST = normDST(DST);
93
112
  // https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
94
113
  if (DST.length > 255) DST = H(concatBytes(asciiToBytes('H2C-OVERSIZE-DST-'), DST));
@@ -118,13 +137,13 @@ export function expand_message_xmd(
118
137
  */
119
138
  export function expand_message_xof(
120
139
  msg: Uint8Array,
121
- DST: UnicodeOrBytes,
140
+ DST: AsciiOrBytes,
122
141
  lenInBytes: number,
123
142
  k: number,
124
143
  H: CHash
125
144
  ): Uint8Array {
126
145
  abytes(msg);
127
- anum(lenInBytes);
146
+ asafenumber(lenInBytes);
128
147
  DST = normDST(DST);
129
148
  // https://www.rfc-editor.org/rfc/rfc9380#section-5.3.3
130
149
  // DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
@@ -154,16 +173,16 @@ export function expand_message_xof(
154
173
  * @returns [u_0, ..., u_(count - 1)], a list of field elements.
155
174
  */
156
175
  export function hash_to_field(msg: Uint8Array, count: number, options: H2COpts): bigint[][] {
157
- _validateObject(options, {
176
+ validateObject(options, {
158
177
  p: 'bigint',
159
178
  m: 'number',
160
179
  k: 'number',
161
180
  hash: 'function',
162
181
  });
163
182
  const { p, k, m, hash, expand, DST } = options;
164
- if (!isHash(options.hash)) throw new Error('expected valid hash');
183
+ asafenumber(hash.outputLen, 'valid hash');
165
184
  abytes(msg);
166
- anum(count);
185
+ asafenumber(count);
167
186
  const log2p = p.toString(2).length;
168
187
  const L = Math.ceil((log2p + k) / 8); // section 5.1 of ietf draft link above
169
188
  const len_in_bytes = count * m * L;
@@ -191,8 +210,8 @@ export function hash_to_field(msg: Uint8Array, count: number, options: H2COpts):
191
210
  return u;
192
211
  }
193
212
 
194
- export type XY<T> = (x: T, y: T) => { x: T; y: T };
195
- export type XYRatio<T> = [T[], T[], T[], T[]]; // xn/xd, yn/yd
213
+ type XY<T> = (x: T, y: T) => { x: T; y: T };
214
+ type XYRatio<T> = [T[], T[], T[], T[]]; // xn/xd, yn/yd
196
215
  export function isogenyMap<T, F extends IField<T>>(field: F, map: XYRatio<T>): XY<T> {
197
216
  // Make same order as in spec
198
217
  const coeff = map.map((i) => Array.from(i).reverse());
@@ -211,38 +230,13 @@ export function isogenyMap<T, F extends IField<T>>(field: F, map: XYRatio<T>): X
211
230
  };
212
231
  }
213
232
 
214
- export type MapToCurve<T> = (scalar: bigint[]) => AffinePoint<T>;
215
-
216
- // Separated from initialization opts, so users won't accidentally change per-curve parameters
217
- // (changing DST is ok!)
218
- export type htfBasicOpts = { DST: UnicodeOrBytes };
219
- export type H2CMethod<P> = (msg: Uint8Array, options?: htfBasicOpts) => P;
220
- // TODO: remove
221
- export type H2CHasherBase<P> = {
222
- hashToCurve: H2CMethod<P>;
223
- hashToScalar: (msg: Uint8Array, options?: htfBasicOpts) => bigint;
224
- };
225
- /**
226
- * RFC 9380 methods, with cofactor clearing. See https://www.rfc-editor.org/rfc/rfc9380#section-3.
227
- *
228
- * * hashToCurve: `map(hash(input))`, encodes RANDOM bytes to curve (WITH hashing)
229
- * * encodeToCurve: `map(hash(input))`, encodes NON-UNIFORM bytes to curve (WITH hashing)
230
- * * mapToCurve: `map(scalars)`, encodes NON-UNIFORM scalars to curve (NO hashing)
231
- */
232
- export type H2CHasher<PC extends PC_ANY> = H2CHasherBase<PC_P<PC>> & {
233
- Point: PC;
234
- encodeToCurve: H2CMethod<PC_P<PC>>;
235
- mapToCurve: MapToCurve<PC_F<PC>>;
236
- defaults: H2COpts & { encodeDST?: UnicodeOrBytes };
237
- };
238
-
239
233
  export const _DST_scalar: Uint8Array = asciiToBytes('HashToScalar-');
240
234
 
241
235
  /** Creates hash-to-curve methods from EC Point and mapToCurve function. See {@link H2CHasher}. */
242
236
  export function createHasher<PC extends PC_ANY>(
243
237
  Point: PC,
244
238
  mapToCurve: MapToCurve<PC_F<PC>>,
245
- defaults: H2COpts & { encodeDST?: UnicodeOrBytes }
239
+ defaults: H2COpts & { encodeDST?: AsciiOrBytes }
246
240
  ): H2CHasher<PC> {
247
241
  if (typeof mapToCurve !== 'function') throw new Error('mapToCurve() must be defined');
248
242
  function map(num: bigint[]): PC_P<PC> {
@@ -256,17 +250,17 @@ export function createHasher<PC extends PC_ANY>(
256
250
  }
257
251
 
258
252
  return {
259
- defaults,
253
+ defaults: Object.freeze(defaults),
260
254
  Point,
261
255
 
262
- hashToCurve(msg: Uint8Array, options?: htfBasicOpts): PC_P<PC> {
256
+ hashToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC> {
263
257
  const opts = Object.assign({}, defaults, options);
264
258
  const u = hash_to_field(msg, 2, opts);
265
259
  const u0 = map(u[0]);
266
260
  const u1 = map(u[1]);
267
261
  return clear(u0.add(u1) as PC_P<PC>);
268
262
  },
269
- encodeToCurve(msg: Uint8Array, options?: htfBasicOpts): PC_P<PC> {
263
+ encodeToCurve(msg: Uint8Array, options?: H2CDSTOpts): PC_P<PC> {
270
264
  const optsDst = defaults.encodeDST ? { DST: defaults.encodeDST } : {};
271
265
  const opts = Object.assign({}, defaults, optsDst, options);
272
266
  const u = hash_to_field(msg, 1, opts);
@@ -274,7 +268,12 @@ export function createHasher<PC extends PC_ANY>(
274
268
  return clear(u0);
275
269
  },
276
270
  /** See {@link H2CHasher} */
277
- mapToCurve(scalars: bigint[]): PC_P<PC> {
271
+ mapToCurve(scalars: bigint | bigint[]): PC_P<PC> {
272
+ // Curves with m=1 accept only single scalar
273
+ if (defaults.m === 1) {
274
+ if (typeof scalars !== 'bigint') throw new Error('expected bigint (m=1)');
275
+ return clear(map([scalars]));
276
+ }
278
277
  if (!Array.isArray(scalars)) throw new Error('expected array of bigints');
279
278
  for (const i of scalars)
280
279
  if (typeof i !== 'bigint') throw new Error('expected array of bigints');
@@ -283,7 +282,7 @@ export function createHasher<PC extends PC_ANY>(
283
282
 
284
283
  // hash_to_scalar can produce 0: https://www.rfc-editor.org/errata/eid8393
285
284
  // RFC 9380, draft-irtf-cfrg-bbs-signatures-08
286
- hashToScalar(msg: Uint8Array, options?: htfBasicOpts): bigint {
285
+ hashToScalar(msg: Uint8Array, options?: H2CDSTOpts): bigint {
287
286
  // @ts-ignore
288
287
  const N = Point.Fn.ORDER;
289
288
  const opts = Object.assign({}, defaults, { p: N, m: 1, DST: _DST_scalar }, options);
@@ -6,21 +6,23 @@
6
6
  */
7
7
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8
8
  import {
9
- _validateObject,
10
9
  abytes,
11
10
  anumber,
12
11
  bytesToNumberBE,
13
12
  bytesToNumberLE,
14
13
  numberToBytesBE,
15
14
  numberToBytesLE,
15
+ validateObject,
16
16
  } from '../utils.ts';
17
17
 
18
+ // Numbers aren't used in x25519 / x448 builds
18
19
  // prettier-ignore
19
- const _0n = BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3);
20
+ const _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2);
20
21
  // prettier-ignore
21
- const _4n = /* @__PURE__ */ BigInt(4), _5n = /* @__PURE__ */ BigInt(5), _7n = /* @__PURE__ */ BigInt(7);
22
+ const _3n = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _5n = /* @__PURE__ */ BigInt(5);
22
23
  // prettier-ignore
23
- const _8n = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9), _16n = /* @__PURE__ */ BigInt(16);
24
+ const _7n = /* @__PURE__ */ BigInt(7), _8n = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9);
25
+ const _16n = /* @__PURE__ */ BigInt(16);
24
26
 
25
27
  // Calculates a modulo b
26
28
  export function mod(a: bigint, b: bigint): bigint {
@@ -281,7 +283,7 @@ export function validateField<T>(field: IField<T>): IField<T> {
281
283
  map[val] = 'function';
282
284
  return map;
283
285
  }, initial);
284
- _validateObject(field, opts);
286
+ validateObject(field, opts);
285
287
  // const max = 16384;
286
288
  // if (field.BYTES < 1 || field.BYTES > max) throw new Error('invalid field');
287
289
  // if (field.BITS < 1 || field.BITS > 8 * max) throw new Error('invalid field');
@@ -6,23 +6,23 @@
6
6
  */
7
7
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
8
8
  import {
9
- _validateObject,
10
9
  abytes,
11
10
  aInRange,
12
11
  bytesToNumberLE,
13
12
  copyBytes,
14
13
  numberToBytesLE,
15
14
  randomBytes,
15
+ validateObject,
16
16
  type CryptoKeys,
17
17
  } from '../utils.ts';
18
- import type { CurveLengths } from './curve.ts';
18
+ import { createKeygen, type CurveLengths } from './curve.ts';
19
19
  import { mod } from './modular.ts';
20
20
 
21
21
  const _0n = BigInt(0);
22
22
  const _1n = BigInt(1);
23
23
  const _2n = BigInt(2);
24
24
 
25
- export type CurveType = {
25
+ export type MontgomeryOpts = {
26
26
  P: bigint; // finite field prime
27
27
  type: 'x25519' | 'x448';
28
28
  adjustScalarBytes: (bytes: Uint8Array) => Uint8Array;
@@ -43,15 +43,15 @@ export type MontgomeryECDH = {
43
43
  keygen: (seed?: Uint8Array) => { secretKey: Uint8Array; publicKey: Uint8Array };
44
44
  };
45
45
 
46
- function validateOpts(curve: CurveType) {
47
- _validateObject(curve, {
46
+ function validateOpts(curve: MontgomeryOpts) {
47
+ validateObject(curve, {
48
48
  adjustScalarBytes: 'function',
49
49
  powPminus2: 'function',
50
50
  });
51
51
  return Object.freeze({ ...curve } as const);
52
52
  }
53
53
 
54
- export function montgomery(curveDef: CurveType): MontgomeryECDH {
54
+ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
55
55
  const CURVE = validateOpts(curveDef);
56
56
  const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = CURVE;
57
57
  const is25519 = type === 'x25519';
@@ -105,6 +105,8 @@ export function montgomery(curveDef: CurveType): MontgomeryECDH {
105
105
  function scalarMultBase(scalar: Uint8Array): Uint8Array {
106
106
  return scalarMult(scalar, GuBytes);
107
107
  }
108
+ const getPublicKey = scalarMultBase;
109
+ const getSharedSecret = scalarMult;
108
110
 
109
111
  // cswap from RFC7748 "example code"
110
112
  function cswap(swap: bigint, x_2: bigint, x_3: bigint): { x_2: bigint; x_3: bigint } {
@@ -170,20 +172,12 @@ export function montgomery(curveDef: CurveType): MontgomeryECDH {
170
172
  abytes(seed, lengths.seed, 'seed');
171
173
  return seed;
172
174
  };
173
- function keygen(seed?: Uint8Array) {
174
- const secretKey = randomSecretKey(seed);
175
- return { secretKey, publicKey: scalarMultBase(secretKey) };
176
- }
177
- const utils = {
178
- randomSecretKey,
179
- randomPrivateKey: randomSecretKey,
180
- };
175
+ const utils = { randomSecretKey };
181
176
 
182
177
  return Object.freeze({
183
- keygen,
184
- getSharedSecret: (secretKey: Uint8Array, publicKey: Uint8Array) =>
185
- scalarMult(secretKey, publicKey),
186
- getPublicKey: (secretKey: Uint8Array): Uint8Array => scalarMultBase(secretKey),
178
+ keygen: createKeygen(randomSecretKey, getPublicKey),
179
+ getSharedSecret,
180
+ getPublicKey,
187
181
  scalarMult,
188
182
  scalarMultBase,
189
183
  utils,
@@ -60,8 +60,8 @@ import {
60
60
  validateObject,
61
61
  } from '../utils.ts';
62
62
  import { pippenger, type CurvePoint, type CurvePointCons } from './curve.ts';
63
- import { _DST_scalar, type H2CMethod, type htfBasicOpts } from './hash-to-curve.js';
64
- import { getMinHashLength, mapHashToField } from './modular.js';
63
+ import { _DST_scalar, type H2CDSTOpts } from './hash-to-curve.ts';
64
+ import { getMinHashLength, mapHashToField } from './modular.ts';
65
65
 
66
66
  // OPRF is designed to be used across network, so we default to serialized values.
67
67
  export type PointBytes = Uint8Array;
@@ -73,9 +73,9 @@ export type OPRFOpts<P extends CurvePoint<any, P>> = {
73
73
  name: string;
74
74
  Point: CurvePointCons<P>; // we don't return Point, so we need generic interface only
75
75
  // Fn: IField<bigint>;
76
- hash: (msg: Bytes) => Bytes;
77
- hashToScalar: (msg: Uint8Array, options: htfBasicOpts) => bigint;
78
- hashToGroup: ((msg: Uint8Array, options: htfBasicOpts) => P) | H2CMethod<P>;
76
+ hash(msg: Bytes): Bytes;
77
+ hashToScalar(msg: Uint8Array, options: H2CDSTOpts): bigint;
78
+ hashToGroup(msg: Uint8Array, options: H2CDSTOpts): P;
79
79
  };
80
80
 
81
81
  export type OPRFKeys = { secretKey: ScalarBytes; publicKey: PointBytes };
@@ -433,7 +433,7 @@ export function createORPF<P extends CurvePoint<any, P>>(opts: OPRFOpts<P>): OPR
433
433
 
434
434
  function deriveKeyPair(ctx: Bytes, seed: Bytes, info: Bytes) {
435
435
  const dst = concatBytes(asciiToBytes('DeriveKeyPair'), ctx);
436
- const msg = concatBytes(seed, encode(info), new Uint8Array([0]));
436
+ const msg = concatBytes(seed, encode(info), Uint8Array.of(0));
437
437
  for (let counter = 0; counter <= 255; counter++) {
438
438
  msg[msg.length - 1] = counter;
439
439
  const skS = opts.hashToScalar(msg, { DST: dst });
@@ -7,7 +7,7 @@
7
7
  * @module
8
8
  */
9
9
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
10
- import { _validateObject, bitGet } from '../utils.ts';
10
+ import { asafenumber, bitGet, validateObject } from '../utils.ts';
11
11
  import { FpInvertBatch, FpPow, type IField, validateField } from './modular.ts';
12
12
 
13
13
  // Grain LFSR (Linear-Feedback Shift Register): https://eprint.iacr.org/2009/109.pdf
@@ -44,7 +44,7 @@ export type PoseidonBasicOpts = {
44
44
  function assertValidPosOpts(opts: PoseidonBasicOpts) {
45
45
  const { Fp, roundsFull } = opts;
46
46
  validateField(Fp);
47
- _validateObject(
47
+ validateObject(
48
48
  opts,
49
49
  {
50
50
  t: 'number',
@@ -55,8 +55,9 @@ function assertValidPosOpts(opts: PoseidonBasicOpts) {
55
55
  isSboxInverse: 'boolean',
56
56
  }
57
57
  );
58
- for (const i of ['t', 'roundsFull', 'roundsPartial'] as const) {
59
- if (!Number.isSafeInteger(opts[i]) || opts[i] < 1) throw new Error('invalid number ' + i);
58
+ for (const k of ['t', 'roundsFull', 'roundsPartial'] as const) {
59
+ asafenumber(opts[k], k);
60
+ if (opts[k] < 1) throw new Error('invalid number ' + k);
60
61
  }
61
62
  if (roundsFull & 1) throw new Error('roundsFull is not even' + roundsFull);
62
63
  }
@@ -322,10 +323,7 @@ export type PoseidonSpongeOpts = Omit<PoseidonOpts, 't'> & {
322
323
  * - https://github.com/arkworks-rs/crypto-primitives/tree/main
323
324
  */
324
325
  export function poseidonSponge(opts: PoseidonSpongeOpts): () => PoseidonSponge {
325
- for (const i of ['rate', 'capacity'] as const) {
326
- if (typeof opts[i] !== 'number' || !Number.isSafeInteger(opts[i]))
327
- throw new Error('invalid number ' + i);
328
- }
326
+ for (const k of ['rate', 'capacity'] as const) asafenumber(opts[k], k);
329
327
  const { rate, capacity } = opts;
330
328
  const t = opts.rate + opts.capacity;
331
329
  // Re-use hash instance between multiple instances