@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.
- package/README.md +442 -273
- package/abstract/bls.d.ts +17 -17
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +14 -9
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +9 -3
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +7 -9
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +12 -16
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +32 -31
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +15 -14
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +7 -5
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +3 -3
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +9 -13
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +4 -4
- package/abstract/oprf.d.ts.map +1 -1
- package/abstract/oprf.js +2 -2
- package/abstract/oprf.js.map +1 -1
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +8 -9
- package/abstract/poseidon.js.map +1 -1
- package/abstract/weierstrass.d.ts +66 -20
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +72 -68
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +3 -9
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +3 -14
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +3 -3
- package/bn254.d.ts.map +1 -1
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +22 -18
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +59 -31
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +17 -8
- package/ed448.d.ts.map +1 -1
- package/ed448.js +69 -52
- package/ed448.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +20 -4
- package/index.js.map +1 -1
- package/misc.js +2 -2
- package/misc.js.map +1 -1
- package/nist.d.ts +20 -2
- package/nist.d.ts.map +1 -1
- package/nist.js +30 -10
- package/nist.js.map +1 -1
- package/package.json +14 -13
- package/secp256k1.d.ts +10 -7
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +15 -16
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +22 -22
- package/src/abstract/curve.ts +19 -5
- package/src/abstract/edwards.ts +20 -23
- package/src/abstract/hash-to-curve.ts +50 -51
- package/src/abstract/modular.ts +7 -5
- package/src/abstract/montgomery.ts +12 -18
- package/src/abstract/oprf.ts +5 -5
- package/src/abstract/poseidon.ts +6 -8
- package/src/abstract/weierstrass.ts +139 -89
- package/src/bls12-381.ts +4 -15
- package/src/bn254.ts +6 -6
- package/src/ed25519.ts +65 -40
- package/src/ed448.ts +87 -69
- package/src/index.ts +19 -3
- package/src/misc.ts +2 -2
- package/src/nist.ts +31 -15
- package/src/secp256k1.ts +16 -18
- package/src/utils.ts +33 -83
- package/src/webcrypto.ts +148 -107
- package/utils.d.ts +4 -20
- package/utils.d.ts.map +1 -1
- package/utils.js +30 -73
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +73 -21
- package/webcrypto.d.ts.map +1 -1
- package/webcrypto.js +101 -76
- package/webcrypto.js.map +1 -1
- package/_shortw_utils.d.ts +0 -19
- package/_shortw_utils.d.ts.map +0 -1
- package/_shortw_utils.js +0 -20
- package/_shortw_utils.js.map +0 -1
- package/abstract/utils.d.ts +0 -5
- package/abstract/utils.d.ts.map +0 -1
- package/abstract/utils.js +0 -23
- package/abstract/utils.js.map +0 -1
- package/jubjub.d.ts +0 -12
- package/jubjub.d.ts.map +0 -1
- package/jubjub.js +0 -15
- package/jubjub.js.map +0 -1
- package/p256.d.ts +0 -16
- package/p256.d.ts.map +0 -1
- package/p256.js +0 -13
- package/p256.js.map +0 -1
- package/p384.d.ts +0 -16
- package/p384.d.ts.map +0 -1
- package/p384.js +0 -13
- package/p384.js.map +0 -1
- package/p521.d.ts +0 -16
- package/p521.d.ts.map +0 -1
- package/p521.js +0 -13
- package/p521.js.map +0 -1
- package/pasta.d.ts +0 -10
- package/pasta.d.ts.map +0 -1
- package/pasta.js +0 -13
- 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
|
-
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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?:
|
|
66
|
-
export(key: CryptoKey, format?:
|
|
67
|
-
convert(key: Key, inFormat?:
|
|
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,
|
|
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:
|
|
84
|
-
format ===
|
|
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:
|
|
87
|
-
const
|
|
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:
|
|
114
|
+
async export(key: CryptoKey, format: WebCryptoFormat): Promise<Key> {
|
|
93
115
|
assertType('public', key);
|
|
94
|
-
const
|
|
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:
|
|
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:
|
|
104
|
-
const crypto =
|
|
124
|
+
async import(key: Key, format: WebCryptoFormat): Promise<CryptoKey> {
|
|
125
|
+
const crypto = getSubtle();
|
|
105
126
|
let keyi: CryptoKey;
|
|
106
|
-
if (format ===
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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 ===
|
|
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:
|
|
126
|
-
const crypto =
|
|
146
|
+
async export(key: CryptoKey, format: WebCryptoFormat): Promise<Key> {
|
|
147
|
+
const crypto = getSubtle();
|
|
127
148
|
assertType('private', key);
|
|
128
|
-
if (format ===
|
|
149
|
+
if (format === TYPE_RAW) {
|
|
129
150
|
// scure-base base64urlnopad could have been used, but we can't add more deps.
|
|
130
|
-
//
|
|
131
|
-
const jwk = await crypto.exportKey(
|
|
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:
|
|
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
|
|
187
|
+
let supported: boolean | undefined;
|
|
151
188
|
return {
|
|
152
189
|
pub: pub as KeyUtils,
|
|
153
190
|
priv: priv as KeyUtils,
|
|
154
|
-
async
|
|
155
|
-
if (
|
|
191
|
+
async isSupported(): Promise<boolean> {
|
|
192
|
+
if (supported !== undefined) return supported;
|
|
156
193
|
try {
|
|
157
|
-
const crypto =
|
|
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,
|
|
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 (
|
|
206
|
+
return (supported = true);
|
|
170
207
|
} catch (e) {
|
|
171
|
-
return (
|
|
208
|
+
return (supported = false);
|
|
172
209
|
}
|
|
173
210
|
},
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
205
|
-
const
|
|
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
|
|
216
|
-
|
|
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(
|
|
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
|
|
231
|
-
const
|
|
232
|
-
const
|
|
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
|
-
|
|
246
|
-
|
|
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?:
|
|
249
|
-
convertSecretKey: (
|
|
250
|
-
|
|
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(
|
|
286
|
+
sign(message: Uint8Array, secretKey: Key, opts?: WebCryptoOpts): Promise<Uint8Array>;
|
|
258
287
|
verify(
|
|
259
288
|
signature: Uint8Array,
|
|
260
|
-
|
|
289
|
+
message: Uint8Array,
|
|
261
290
|
publicKey: Key,
|
|
262
291
|
opts?: WebCryptoOpts
|
|
263
292
|
): Promise<boolean>;
|
|
264
293
|
};
|
|
265
294
|
export type WebCryptoECDH = {
|
|
266
|
-
getSharedSecret(
|
|
295
|
+
getSharedSecret(secA: Uint8Array, pubB: Uint8Array, opts?: WebCryptoOpts): Promise<Uint8Array>;
|
|
267
296
|
};
|
|
268
|
-
export type
|
|
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
|
|
301
|
+
function wrapECDSA(
|
|
273
302
|
curve: 'P-256' | 'P-384' | 'P-521',
|
|
274
303
|
hash: string,
|
|
275
304
|
keyLen: number,
|
|
276
|
-
|
|
277
|
-
):
|
|
305
|
+
pkcs8header: string
|
|
306
|
+
): WebCryptoECDSA {
|
|
278
307
|
const ECDH_ALGO = { name: 'ECDH', namedCurve: curve };
|
|
279
|
-
const keys = createKeyUtils({ name: 'ECDSA', namedCurve: curve }, false, keyLen,
|
|
280
|
-
const keysEcdh = createKeyUtils(ECDH_ALGO, true, keyLen,
|
|
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
|
-
|
|
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
|
-
|
|
324
|
+
pkcs8header: string
|
|
295
325
|
): WebCryptoEdDSA {
|
|
296
|
-
const keys = createKeyUtils(curve, false, keyLen,
|
|
326
|
+
const keys = createKeyUtils(curve, false, keyLen, pkcs8header);
|
|
297
327
|
return Object.freeze({
|
|
298
328
|
name: curve,
|
|
299
|
-
|
|
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
|
-
|
|
340
|
+
pkcs8header: string
|
|
310
341
|
): WebCryptoMontgomery {
|
|
311
|
-
const keys = createKeyUtils(curve, true, keyLen,
|
|
342
|
+
const keys = createKeyUtils(curve, true, keyLen, pkcs8header);
|
|
312
343
|
return Object.freeze({
|
|
313
344
|
name: curve,
|
|
314
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
68
|
-
declare
|
|
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":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["src/utils.ts"],"names":[],"mappings":"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"}
|