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

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 (118) hide show
  1. package/README.md +442 -273
  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 +2 -2
  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/weierstrass.d.ts +66 -20
  32. package/abstract/weierstrass.d.ts.map +1 -1
  33. package/abstract/weierstrass.js +72 -68
  34. package/abstract/weierstrass.js.map +1 -1
  35. package/bls12-381.d.ts +3 -9
  36. package/bls12-381.d.ts.map +1 -1
  37. package/bls12-381.js +3 -14
  38. package/bls12-381.js.map +1 -1
  39. package/bn254.d.ts +3 -3
  40. package/bn254.d.ts.map +1 -1
  41. package/bn254.js.map +1 -1
  42. package/ed25519.d.ts +22 -18
  43. package/ed25519.d.ts.map +1 -1
  44. package/ed25519.js +59 -31
  45. package/ed25519.js.map +1 -1
  46. package/ed448.d.ts +17 -8
  47. package/ed448.d.ts.map +1 -1
  48. package/ed448.js +69 -52
  49. package/ed448.js.map +1 -1
  50. package/index.d.ts +1 -0
  51. package/index.js +20 -4
  52. package/index.js.map +1 -1
  53. package/misc.js +2 -2
  54. package/misc.js.map +1 -1
  55. package/nist.d.ts +20 -2
  56. package/nist.d.ts.map +1 -1
  57. package/nist.js +30 -10
  58. package/nist.js.map +1 -1
  59. package/package.json +14 -13
  60. package/secp256k1.d.ts +10 -7
  61. package/secp256k1.d.ts.map +1 -1
  62. package/secp256k1.js +15 -16
  63. package/secp256k1.js.map +1 -1
  64. package/src/abstract/bls.ts +22 -22
  65. package/src/abstract/curve.ts +19 -5
  66. package/src/abstract/edwards.ts +20 -23
  67. package/src/abstract/hash-to-curve.ts +50 -51
  68. package/src/abstract/modular.ts +7 -5
  69. package/src/abstract/montgomery.ts +12 -18
  70. package/src/abstract/oprf.ts +5 -5
  71. package/src/abstract/poseidon.ts +6 -8
  72. package/src/abstract/weierstrass.ts +139 -89
  73. package/src/bls12-381.ts +4 -15
  74. package/src/bn254.ts +6 -6
  75. package/src/ed25519.ts +65 -40
  76. package/src/ed448.ts +87 -69
  77. package/src/index.ts +19 -3
  78. package/src/misc.ts +2 -2
  79. package/src/nist.ts +31 -15
  80. package/src/secp256k1.ts +16 -18
  81. package/src/utils.ts +33 -83
  82. package/src/webcrypto.ts +148 -107
  83. package/utils.d.ts +4 -20
  84. package/utils.d.ts.map +1 -1
  85. package/utils.js +30 -73
  86. package/utils.js.map +1 -1
  87. package/webcrypto.d.ts +73 -21
  88. package/webcrypto.d.ts.map +1 -1
  89. package/webcrypto.js +101 -76
  90. package/webcrypto.js.map +1 -1
  91. package/_shortw_utils.d.ts +0 -19
  92. package/_shortw_utils.d.ts.map +0 -1
  93. package/_shortw_utils.js +0 -20
  94. package/_shortw_utils.js.map +0 -1
  95. package/abstract/utils.d.ts +0 -5
  96. package/abstract/utils.d.ts.map +0 -1
  97. package/abstract/utils.js +0 -23
  98. package/abstract/utils.js.map +0 -1
  99. package/jubjub.d.ts +0 -12
  100. package/jubjub.d.ts.map +0 -1
  101. package/jubjub.js +0 -15
  102. package/jubjub.js.map +0 -1
  103. package/p256.d.ts +0 -16
  104. package/p256.d.ts.map +0 -1
  105. package/p256.js +0 -13
  106. package/p256.js.map +0 -1
  107. package/p384.d.ts +0 -16
  108. package/p384.d.ts.map +0 -1
  109. package/p384.js +0 -13
  110. package/p384.js.map +0 -1
  111. package/p521.d.ts +0 -16
  112. package/p521.d.ts.map +0 -1
  113. package/p521.js +0 -13
  114. package/p521.js.map +0 -1
  115. package/pasta.d.ts +0 -10
  116. package/pasta.d.ts.map +0 -1
  117. package/pasta.js +0 -13
  118. package/pasta.js.map +0 -1
package/src/webcrypto.ts CHANGED
@@ -14,7 +14,7 @@
14
14
  -> "If format is "raw":" -> "If usages contains a value which is not "verify"
15
15
  then throw a SyntaxError."
16
16
  - SPKI (Simple public-key infrastructure) is public-key-only
17
- - PCKS8 is secret-key-only
17
+ - PKCS8 is secret-key-only
18
18
  - No way to get public key from secret key, but we convert to jwk and then create it manually, since jwk secret key is priv+pub.
19
19
  - Noble supports generating keys for both sign, verify & getSharedSecret,
20
20
  but JWK key includes usage, which forces us to patch it (non-JWK is ok)
@@ -37,14 +37,43 @@ There seems no reasonable way to check for availability, other than actually cal
37
37
  * @module
38
38
  */
39
39
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
40
- import { concatBytes, hexToBytes } from './utils.ts';
41
40
 
42
- function getWebcryptoSubtle(): any {
43
- const subtle: any = globalThis?.crypto?.subtle;
44
- if (typeof subtle === 'object' && subtle != null) return subtle;
41
+ /** Raw type */
42
+ const TYPE_RAW = 'raw';
43
+ const TYPE_JWK = 'jwk';
44
+ const TYPE_SPKI = 'spki';
45
+ const TYPE_PKCS = 'pkcs8';
46
+ export type WebCryptoFormat =
47
+ | typeof TYPE_RAW
48
+ | typeof TYPE_JWK
49
+ | typeof TYPE_SPKI
50
+ | typeof TYPE_PKCS;
51
+ /** WebCrypto keys can be in raw, jwk, pkcs8/spki formats. Raw is internal and fragile. */
52
+ export type WebCryptoOpts = {
53
+ formatSec?: WebCryptoFormat;
54
+ formatPub?: WebCryptoFormat;
55
+ };
56
+ // default formats
57
+ const dfsec = TYPE_PKCS;
58
+ const dfpub = TYPE_SPKI;
59
+
60
+ function getSubtle(): any {
61
+ const s: any = globalThis?.crypto?.subtle;
62
+ if (typeof s === 'object' && s != null) return s;
45
63
  throw new Error('crypto.subtle must be defined');
46
64
  }
47
65
 
66
+ function createKeygenA(randomSecretKey: any, getPublicKey: any) {
67
+ return async function keygenA(_seed?: Uint8Array) {
68
+ const secretKey = await randomSecretKey();
69
+ return { secretKey, publicKey: await getPublicKey(secretKey) };
70
+ };
71
+ }
72
+
73
+ function hexToBytesUns(hex: string): Uint8Array {
74
+ return Uint8Array.from(hex.match(/(\w\w)/g)!, (b) => Number.parseInt(b, 16));
75
+ }
76
+
48
77
  // Trying to do generics here creates hell on conversion and usage
49
78
  type JsonWebKey = {
50
79
  crv?: string;
@@ -54,7 +83,6 @@ type JsonWebKey = {
54
83
  y?: string;
55
84
  [key: string]: unknown;
56
85
  };
57
- type Format = 'raw' | 'jwk' | 'spki' | 'pkcs8';
58
86
  type Key = JsonWebKey | Uint8Array;
59
87
  type CryptoKey = Awaited<ReturnType<typeof crypto.subtle.importKey>>;
60
88
  type KeyUsage = 'deriveBits' | 'deriveKey' | 'sign' | 'verify';
@@ -62,73 +90,66 @@ type Algo = string | { name: string; namedCurve: string };
62
90
  type SigAlgo = string | { name: string; hash?: { name: string } };
63
91
 
64
92
  type KeyUtils = {
65
- import(key: Key, format?: Format): Promise<CryptoKey>;
66
- export(key: CryptoKey, format?: Format): Promise<Key>;
67
- convert(key: Key, inFormat?: Format, outFormat?: Format): Promise<Key>;
93
+ import(key: Key, format?: WebCryptoFormat): Promise<CryptoKey>;
94
+ export(key: CryptoKey, format?: WebCryptoFormat): Promise<Key>;
95
+ convert(key: Key, inFormat?: WebCryptoFormat, outFormat?: WebCryptoFormat): Promise<Key>;
68
96
  };
69
- export type WebCryptoGetPubOpts = {
70
- secFormat?: Format;
71
- pubFormat?: Format;
72
- };
73
- const _format = 'raw';
74
97
 
75
98
  function assertType(type: 'private' | 'public', key: any) {
76
99
  if (key.type !== type) throw new Error(`invalid key type, expected ${type}`);
77
100
  }
78
101
 
79
- function createKeyUtils(algo: Algo, derive: boolean, keyLen: number, pcks8header: string) {
102
+ function createKeyUtils(algo: Algo, derive: boolean, keyLen: number, pkcs8header: string) {
80
103
  const secUsage: KeyUsage[] = derive ? ['deriveBits'] : ['sign'];
81
104
  const pubUsage: KeyUsage[] = derive ? [] : ['verify'];
82
105
  // Return Uint8Array instead of ArrayBuffer
83
- const arrBufToU8 = (res: Key, format: Format) =>
84
- format === 'jwk' ? res : new Uint8Array(res as ArrayBuffer);
106
+ const arrBufToU8 = (res: Key, format: WebCryptoFormat) =>
107
+ format === TYPE_JWK ? res : new Uint8Array(res as unknown as ArrayBuffer);
85
108
  const pub: KeyUtils = {
86
- async import(key: Key, format: Format = _format): Promise<CryptoKey> {
87
- const crypto = getWebcryptoSubtle();
88
- const keyi: CryptoKey = await crypto.importKey(format, key, algo, true, pubUsage);
109
+ async import(key: Key, format: WebCryptoFormat): Promise<CryptoKey> {
110
+ const keyi: CryptoKey = await getSubtle().importKey(format, key, algo, true, pubUsage);
89
111
  assertType('public', keyi);
90
112
  return keyi;
91
113
  },
92
- async export(key: CryptoKey, format: Format = _format): Promise<Key> {
114
+ async export(key: CryptoKey, format: WebCryptoFormat): Promise<Key> {
93
115
  assertType('public', key);
94
- const crypto = getWebcryptoSubtle();
95
- const keyi = await crypto.exportKey(format, key);
116
+ const keyi = await getSubtle().exportKey(format, key);
96
117
  return arrBufToU8(keyi, format);
97
118
  },
98
- async convert(key: Key, inFormat: Format = _format, outFormat: Format = _format): Promise<Key> {
119
+ async convert(key: Key, inFormat: WebCryptoFormat, outFormat: WebCryptoFormat): Promise<Key> {
99
120
  return pub.export(await pub.import(key, inFormat), outFormat);
100
121
  },
101
122
  };
102
123
  const priv: KeyUtils = {
103
- async import(key: Key, format: Format = _format): Promise<CryptoKey> {
104
- const crypto = getWebcryptoSubtle();
124
+ async import(key: Key, format: WebCryptoFormat): Promise<CryptoKey> {
125
+ const crypto = getSubtle();
105
126
  let keyi: CryptoKey;
106
- if (format === 'raw') {
127
+ if (format === TYPE_RAW) {
107
128
  // Chrome, node, bun, deno: works
108
129
  // Safari, Firefox: Data provided to an operation does not meet requirements
109
130
  // This is the best one can do. JWK can't be used: it contains public key component inside.
110
- keyi = await crypto.importKey(
111
- 'pkcs8',
112
- concatBytes(hexToBytes(pcks8header), key as Uint8Array),
113
- algo,
114
- true,
115
- secUsage
116
- );
131
+ const k = key as Uint8Array;
132
+ const head = hexToBytesUns(pkcs8header);
133
+ const all = new Uint8Array(head.length + k.length);
134
+ all.set(head, 0);
135
+ all.set(k, head.length);
136
+
137
+ keyi = await crypto.importKey(TYPE_PKCS, all, algo, true, secUsage);
117
138
  } else {
118
139
  // Fix import of ECDSA keys into ECDH, other formats are ok
119
- if (derive && format === 'jwk') key = { ...key, key_ops: secUsage };
140
+ if (derive && format === TYPE_JWK) key = { ...key, key_ops: secUsage };
120
141
  keyi = await crypto.importKey(format, key, algo, true, secUsage);
121
142
  }
122
143
  assertType('private', keyi);
123
144
  return keyi;
124
145
  },
125
- async export(key: CryptoKey, format: Format = _format): Promise<Key> {
126
- const crypto = getWebcryptoSubtle();
146
+ async export(key: CryptoKey, format: WebCryptoFormat): Promise<Key> {
147
+ const crypto = getSubtle();
127
148
  assertType('private', key);
128
- if (format === 'raw') {
149
+ if (format === TYPE_RAW) {
129
150
  // scure-base base64urlnopad could have been used, but we can't add more deps.
130
- // pcks8 would be even more fragile
131
- const jwk = await crypto.exportKey('jwk', key);
151
+ // pkcs8 would be even more fragile
152
+ const jwk = await crypto.exportKey(TYPE_JWK, key);
132
153
  const base64 = jwk.d.replace(/-/g, '+').replace(/_/g, '/'); // base64url
133
154
  const pad = base64.length % 4 ? '='.repeat(4 - (base64.length % 4)) : ''; // add padding
134
155
  const binary = atob(base64 + pad);
@@ -142,22 +163,38 @@ function createKeyUtils(algo: Algo, derive: boolean, keyLen: number, pcks8header
142
163
  const keyi = await crypto.exportKey(format, key);
143
164
  return arrBufToU8(keyi, format);
144
165
  },
145
- async convert(key: Key, inFormat: Format = _format, outFormat: Format = _format): Promise<Key> {
166
+ async convert(key: Key, inFormat: WebCryptoFormat, outFormat: WebCryptoFormat): Promise<Key> {
146
167
  return priv.export(await priv.import(key, inFormat), outFormat);
147
168
  },
148
169
  };
170
+ async function getPublicKey(secretKey: Key, opts: WebCryptoOpts = {}): Promise<Key> {
171
+ const fsec = opts.formatSec ?? dfsec;
172
+ const fpub = opts.formatPub ?? dfpub;
173
+ // Export to jwk, remove private scalar and then convert to format
174
+ const jwk = (
175
+ fsec === TYPE_JWK ? { ...secretKey } : await priv.convert(secretKey, fsec, TYPE_JWK)
176
+ ) as JsonWebKey;
177
+ delete jwk.d;
178
+ jwk.key_ops = pubUsage;
179
+ if (fpub === TYPE_JWK) return jwk;
180
+ return pub.convert(jwk, TYPE_JWK, fpub);
181
+ }
182
+ async function randomSecretKey(format: WebCryptoFormat = dfsec): Promise<Key> {
183
+ const keyPair = await getSubtle().generateKey(algo, true, secUsage);
184
+ return priv.export(keyPair.privateKey, format);
185
+ }
149
186
  // Key generation could be slow, so we cache result once.
150
- let available: boolean | undefined;
187
+ let supported: boolean | undefined;
151
188
  return {
152
189
  pub: pub as KeyUtils,
153
190
  priv: priv as KeyUtils,
154
- async isAvailable(): Promise<boolean> {
155
- if (available !== undefined) return available;
191
+ async isSupported(): Promise<boolean> {
192
+ if (supported !== undefined) return supported;
156
193
  try {
157
- const crypto = getWebcryptoSubtle();
194
+ const crypto = getSubtle();
158
195
  const key = await crypto.generateKey(algo, true, secUsage);
159
196
  // Deno is broken and generates key for unsupported curves, but then fails on export
160
- await priv.export(key.privateKey, 'jwk');
197
+ await priv.export(key.privateKey, TYPE_JWK);
161
198
  // Bun fails on derive for x25519, but not x448
162
199
  if (derive) {
163
200
  await crypto.deriveBits(
@@ -166,44 +203,26 @@ function createKeyUtils(algo: Algo, derive: boolean, keyLen: number, pcks8header
166
203
  8
167
204
  );
168
205
  }
169
- return (available = true);
206
+ return (supported = true);
170
207
  } catch (e) {
171
- return (available = false);
208
+ return (supported = false);
172
209
  }
173
210
  },
174
- // We support different input / output formats since there is no 'spki' secret key
175
- async getPublicKey(secretKey: Key, opts: WebCryptoGetPubOpts = {}): Promise<Key> {
176
- const fpriv = opts.secFormat ?? _format;
177
- const fpub = opts.pubFormat ?? fpriv;
178
- // Export to jwk, remove private scalar and then convert to format
179
- const jwk = (
180
- fpriv === 'jwk' ? { ...secretKey } : await priv.convert(secretKey, fpriv, 'jwk')
181
- ) as JsonWebKey;
182
- delete jwk.d;
183
- jwk.key_ops = pubUsage;
184
- if (fpub === 'jwk') return jwk;
185
- return pub.convert(jwk, 'jwk', fpub);
186
- },
211
+ getPublicKey,
212
+ keygen: createKeygenA(randomSecretKey, getPublicKey),
187
213
  utils: {
188
- async randomSecretKey(format: Format = _format): Promise<Key> {
189
- const crypto = getWebcryptoSubtle();
190
- const keyPair = await crypto.generateKey(algo, true, secUsage);
191
- return priv.export(keyPair.privateKey, format);
192
- },
214
+ randomSecretKey,
193
215
  convertPublicKey: pub.convert as KeyUtils['convert'],
194
216
  convertSecretKey: priv.convert as KeyUtils['convert'],
195
217
  },
196
218
  };
197
219
  }
198
220
 
199
- type WebCryptoOpts = { format?: Format };
200
-
201
- function createSigner(keys: ReturnType<typeof createKeyUtils>, algo: SigAlgo) {
221
+ function createSigner(keys: ReturnType<typeof createKeyUtils>, algo: SigAlgo): WebCryptoSigner {
202
222
  return {
203
223
  async sign(msgHash: Uint8Array, secretKey: Key, opts: WebCryptoOpts = {}): Promise<Uint8Array> {
204
- const crypto = getWebcryptoSubtle();
205
- const key = await keys.priv.import(secretKey, opts.format || _format);
206
- const sig = await crypto.sign(algo, key, msgHash);
224
+ const key = await keys.priv.import(secretKey, opts.formatSec ?? dfsec);
225
+ const sig = await getSubtle().sign(algo, key, msgHash);
207
226
  return new Uint8Array(sig);
208
227
  },
209
228
  async verify(
@@ -212,14 +231,17 @@ function createSigner(keys: ReturnType<typeof createKeyUtils>, algo: SigAlgo) {
212
231
  publicKey: Key,
213
232
  opts: WebCryptoOpts = {}
214
233
  ): Promise<boolean> {
215
- const crypto = getWebcryptoSubtle();
216
- const key = await keys.pub.import(publicKey, opts.format || _format);
217
- return await crypto.verify(algo, key, signature, msgHash);
234
+ const key = await keys.pub.import(publicKey, opts.formatPub ?? dfpub);
235
+ return await getSubtle().verify(algo, key, signature, msgHash);
218
236
  },
219
237
  };
220
238
  }
221
239
 
222
- function createECDH(keys: ReturnType<typeof createKeyUtils>, algo: Algo, keyLen: number) {
240
+ function createECDH(
241
+ keys: ReturnType<typeof createKeyUtils>,
242
+ algo: Algo,
243
+ keyLen: number
244
+ ): WebCryptoECDH {
223
245
  return {
224
246
  async getSharedSecret(
225
247
  secretKeyA: Uint8Array,
@@ -227,10 +249,9 @@ function createECDH(keys: ReturnType<typeof createKeyUtils>, algo: Algo, keyLen:
227
249
  opts: WebCryptoOpts = {}
228
250
  ): Promise<Uint8Array> {
229
251
  // if (_isCompressed !== true) throw new Error('WebCrypto only supports compressed keys');
230
- const crypto = getWebcryptoSubtle();
231
- const secKey = await keys.priv.import(secretKeyA, opts.format || _format);
232
- const pubKey = await keys.pub.import(publicKeyB, opts.format || _format);
233
- const shared = await crypto.deriveBits(
252
+ const secKey = await keys.priv.import(secretKeyA, opts.formatSec || dfsec);
253
+ const pubKey = await keys.pub.import(publicKeyB, opts.formatPub || dfpub);
254
+ const shared = await getSubtle().deriveBits(
234
255
  { name: typeof algo === 'string' ? algo : algo.name, public: pubKey },
235
256
  secKey,
236
257
  8 * keyLen
@@ -242,46 +263,55 @@ function createECDH(keys: ReturnType<typeof createKeyUtils>, algo: Algo, keyLen:
242
263
 
243
264
  type WebCryptoBaseCurve = {
244
265
  name: string;
245
- isAvailable(): Promise<boolean>;
246
- getPublicKey(secretKey: Key, opts?: WebCryptoGetPubOpts): Promise<Key>;
266
+ isSupported(): Promise<boolean>;
267
+ keygen(): Promise<{ secretKey: Uint8Array; publicKey: Uint8Array }>;
268
+ getPublicKey(secretKey: Key, opts?: WebCryptoOpts): Promise<Key>;
247
269
  utils: {
248
- randomSecretKey: (format?: Format) => Promise<Key>;
249
- convertSecretKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
250
- convertPublicKey: (key: Key, inFormat?: Format, outFormat?: Format) => Promise<Key>;
270
+ randomSecretKey: (format?: WebCryptoFormat) => Promise<Key>;
271
+ convertSecretKey: (
272
+ key: Key,
273
+ inFormat?: WebCryptoFormat,
274
+ outFormat?: WebCryptoFormat
275
+ ) => Promise<Key>;
276
+ convertPublicKey: (
277
+ key: Key,
278
+ inFormat?: WebCryptoFormat,
279
+ outFormat?: WebCryptoFormat
280
+ ) => Promise<Key>;
251
281
  };
252
282
  };
253
283
 
254
284
  // Specific per-curve methods - no reason to export them; we can't "add" a new curve
255
- // export type WebCryptoSigner = ReturnType<typeof createSigner>;
256
285
  export type WebCryptoSigner = {
257
- sign(msgHash: Uint8Array, privateKey: Key, opts?: WebCryptoOpts): Promise<Uint8Array>;
286
+ sign(message: Uint8Array, secretKey: Key, opts?: WebCryptoOpts): Promise<Uint8Array>;
258
287
  verify(
259
288
  signature: Uint8Array,
260
- msgHash: Uint8Array,
289
+ message: Uint8Array,
261
290
  publicKey: Key,
262
291
  opts?: WebCryptoOpts
263
292
  ): Promise<boolean>;
264
293
  };
265
294
  export type WebCryptoECDH = {
266
- getSharedSecret(priv: Uint8Array, pub: Uint8Array, opts?: WebCryptoOpts): Promise<Uint8Array>;
295
+ getSharedSecret(secA: Uint8Array, pubB: Uint8Array, opts?: WebCryptoOpts): Promise<Uint8Array>;
267
296
  };
268
- export type WebCryptoNIST = WebCryptoBaseCurve & WebCryptoSigner & WebCryptoECDH;
297
+ export type WebCryptoECDSA = WebCryptoBaseCurve & WebCryptoSigner & WebCryptoECDH;
269
298
  export type WebCryptoEdDSA = WebCryptoBaseCurve & WebCryptoSigner;
270
299
  export type WebCryptoMontgomery = WebCryptoBaseCurve & WebCryptoECDH;
271
300
 
272
- function wrapNIST(
301
+ function wrapECDSA(
273
302
  curve: 'P-256' | 'P-384' | 'P-521',
274
303
  hash: string,
275
304
  keyLen: number,
276
- pcks8header: string
277
- ): WebCryptoNIST {
305
+ pkcs8header: string
306
+ ): WebCryptoECDSA {
278
307
  const ECDH_ALGO = { name: 'ECDH', namedCurve: curve };
279
- const keys = createKeyUtils({ name: 'ECDSA', namedCurve: curve }, false, keyLen, pcks8header);
280
- const keysEcdh = createKeyUtils(ECDH_ALGO, true, keyLen, pcks8header);
308
+ const keys = createKeyUtils({ name: 'ECDSA', namedCurve: curve }, false, keyLen, pkcs8header);
309
+ const keysEcdh = createKeyUtils(ECDH_ALGO, true, keyLen, pkcs8header);
281
310
  return Object.freeze({
282
311
  name: curve,
283
- isAvailable: keys.isAvailable,
312
+ isSupported: keys.isSupported,
284
313
  getPublicKey: keys.getPublicKey,
314
+ keygen: createKeygenA(keys.utils.randomSecretKey, keys.getPublicKey),
285
315
  ...createSigner(keys, { name: 'ECDSA', hash: { name: hash } }),
286
316
  ...createECDH(keysEcdh, ECDH_ALGO, keyLen),
287
317
  utils: keys.utils,
@@ -291,13 +321,14 @@ function wrapNIST(
291
321
  function wrapEdDSA(
292
322
  curve: 'Ed25519' | 'Ed448',
293
323
  keyLen: number,
294
- pcks8header: string
324
+ pkcs8header: string
295
325
  ): WebCryptoEdDSA {
296
- const keys = createKeyUtils(curve, false, keyLen, pcks8header);
326
+ const keys = createKeyUtils(curve, false, keyLen, pkcs8header);
297
327
  return Object.freeze({
298
328
  name: curve,
299
- isAvailable: keys.isAvailable,
329
+ isSupported: keys.isSupported,
300
330
  getPublicKey: keys.getPublicKey,
331
+ keygen: createKeygenA(keys.utils.randomSecretKey, keys.getPublicKey),
301
332
  ...createSigner(keys, { name: curve }),
302
333
  utils: keys.utils,
303
334
  });
@@ -306,57 +337,67 @@ function wrapEdDSA(
306
337
  function wrapMontgomery(
307
338
  curve: 'X25519' | 'X448',
308
339
  keyLen: number,
309
- pcks8header: string
340
+ pkcs8header: string
310
341
  ): WebCryptoMontgomery {
311
- const keys = createKeyUtils(curve, true, keyLen, pcks8header);
342
+ const keys = createKeyUtils(curve, true, keyLen, pkcs8header);
312
343
  return Object.freeze({
313
344
  name: curve,
314
- isAvailable: keys.isAvailable,
345
+ isSupported: keys.isSupported,
315
346
  getPublicKey: keys.getPublicKey,
347
+ keygen: createKeygenA(keys.utils.randomSecretKey, keys.getPublicKey),
316
348
  ...createECDH(keys, curve, keyLen),
317
349
  utils: keys.utils,
318
350
  });
319
351
  }
320
352
 
321
- export const p256: WebCryptoNIST = /* @__PURE__ */ wrapNIST(
353
+ /** Friendly wrapper over built-in WebCrypto NIST P-256 (secp256r1). */
354
+ export const p256: WebCryptoECDSA = /* @__PURE__ */ wrapECDSA(
322
355
  'P-256',
323
356
  'SHA-256',
324
357
  32,
325
358
  '3041020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420'
326
359
  );
327
- export const p384: WebCryptoNIST = /* @__PURE__ */ wrapNIST(
360
+
361
+ /** Friendly wrapper over built-in WebCrypto NIST P-384 (secp384r1). */
362
+ export const p384: WebCryptoECDSA = /* @__PURE__ */ wrapECDSA(
328
363
  'P-384',
329
364
  'SHA-384',
330
365
  48,
331
366
  '304e020100301006072a8648ce3d020106052b81040022043730350201010430'
332
367
  );
333
- export const p521: WebCryptoNIST = /* @__PURE__ */ wrapNIST(
368
+
369
+ /** Friendly wrapper over built-in WebCrypto NIST P-521 (secp521r1). */
370
+ export const p521: WebCryptoECDSA = /* @__PURE__ */ wrapECDSA(
334
371
  'P-521',
335
372
  'SHA-512',
336
373
  66,
337
374
  '3060020100301006072a8648ce3d020106052b81040023044930470201010442'
338
375
  );
339
376
 
377
+ /** Friendly wrapper over built-in WebCrypto ed25519. */
340
378
  export const ed25519: WebCryptoEdDSA = /* @__PURE__ */ wrapEdDSA(
341
379
  'Ed25519',
342
380
  32,
343
381
  '302e020100300506032b657004220420'
344
382
  );
383
+
384
+ /** Friendly wrapper over built-in WebCrypto ed448. */
345
385
  export const ed448: WebCryptoEdDSA = /* @__PURE__ */ wrapEdDSA(
346
386
  'Ed448',
347
387
  57,
348
388
  '3047020100300506032b6571043b0439'
349
389
  );
350
390
 
391
+ /** Friendly wrapper over built-in WebCrypto x25519 (ECDH over Curve25519). */
351
392
  export const x25519: WebCryptoMontgomery = /* @__PURE__ */ wrapMontgomery(
352
393
  'X25519',
353
394
  32,
354
395
  '302e020100300506032b656e04220420'
355
396
  );
397
+
398
+ /** Friendly wrapper over built-in WebCrypto x448 (ECDH over Curve448). */
356
399
  export const x448: WebCryptoMontgomery = /* @__PURE__ */ wrapMontgomery(
357
400
  'X448',
358
401
  56,
359
402
  '3046020100300506032b656f043a0438'
360
403
  );
361
-
362
- export const supportsWc = (a: WebCryptoBaseCurve): Promise<boolean> => a.isAvailable();
package/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { abytes, anumber, bytesToHex, bytesToUtf8, concatBytes, hexToBytes, isBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';
1
+ export { abytes, anumber, bytesToHex, concatBytes, hexToBytes, isBytes, randomBytes, } from '@noble/hashes/utils.js';
2
2
  export type CHash = {
3
3
  (message: Uint8Array): Uint8Array;
4
4
  blockLen: number;
@@ -9,6 +9,7 @@ export type CHash = {
9
9
  };
10
10
  export type FHash = (message: Uint8Array) => Uint8Array;
11
11
  export declare function abool(value: boolean, title?: string): boolean;
12
+ export declare function asafenumber(value: number, title?: string): void;
12
13
  export declare function numberToHexUnpadded(num: number | bigint): string;
13
14
  export declare function hexToNumber(hex: string): bigint;
14
15
  export declare function bytesToNumberBE(bytes: Uint8Array): bigint;
@@ -64,25 +65,8 @@ type Pred<T> = (v: Uint8Array) => T | undefined;
64
65
  * const drbg = createHmacDRBG<Key>(32, 32, hmac);
65
66
  * drbg(seed, bytesToKey); // bytesToKey must return Key or undefined
66
67
  */
67
- export declare function createHmacDrbg<T>(hashLen: number, qByteLen: number, hmacFn: (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array): (seed: Uint8Array, predicate: Pred<T>) => T;
68
- declare const validatorFns: {
69
- readonly bigint: (val: any) => boolean;
70
- readonly function: (val: any) => boolean;
71
- readonly boolean: (val: any) => boolean;
72
- readonly string: (val: any) => boolean;
73
- readonly stringOrUint8Array: (val: any) => boolean;
74
- readonly isSafeInteger: (val: any) => boolean;
75
- readonly array: (val: any) => boolean;
76
- readonly field: (val: any, object: any) => any;
77
- readonly hash: (val: any) => boolean;
78
- };
79
- type Validator = keyof typeof validatorFns;
80
- type ValMap<T extends Record<string, any>> = {
81
- [K in keyof T]?: Validator;
82
- };
83
- export declare function validateObject<T extends Record<string, any>>(object: T, validators: ValMap<T>, optValidators?: ValMap<T>): T;
84
- export declare function isHash(val: CHash): boolean;
85
- export declare function _validateObject(object: Record<string, any>, fields: Record<string, string>, optFields?: Record<string, string>): void;
68
+ export declare function createHmacDrbg<T>(hashLen: number, qByteLen: number, hmacFn: (key: Uint8Array, message: Uint8Array) => Uint8Array): (seed: Uint8Array, predicate: Pred<T>) => T;
69
+ export declare function validateObject(object: Record<string, any>, fields?: Record<string, string>, optFields?: Record<string, string>): void;
86
70
  /**
87
71
  * throws not implemented error
88
72
  */
package/utils.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"}