react-native-quick-crypto 1.0.1 → 1.0.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.
@@ -271,6 +271,120 @@ async function aesGcmCipher(mode, key, data, algorithm) {
271
271
  return result.buffer;
272
272
  }
273
273
  }
274
+ async function aesKwCipher(mode, key, data) {
275
+ const isWrap = mode === CipherOrWrapMode.kWebCryptoCipherEncrypt;
276
+
277
+ // AES-KW requires input to be a multiple of 8 bytes (64 bits)
278
+ if (data.byteLength % 8 !== 0) {
279
+ throw (0, _errors.lazyDOMException)(`AES-KW input length must be a multiple of 8 bytes, got ${data.byteLength}`, 'OperationError');
280
+ }
281
+
282
+ // AES-KW requires at least 16 bytes of input (128 bits)
283
+ if (isWrap && data.byteLength < 16) {
284
+ throw (0, _errors.lazyDOMException)(`AES-KW input must be at least 16 bytes, got ${data.byteLength}`, 'OperationError');
285
+ }
286
+
287
+ // Get cipher type based on key length
288
+ const keyLength = key.algorithm.length;
289
+ // Use aes*-wrap for both operations (matching Node.js)
290
+ const cipherType = `aes${keyLength}-wrap`;
291
+
292
+ // Export key material
293
+ const exportedKey = key.keyObject.export();
294
+ const cipherKey = (0, _conversion.bufferLikeToArrayBuffer)(exportedKey);
295
+
296
+ // AES-KW uses a default IV as specified in RFC 3394
297
+ const defaultWrapIV = new Uint8Array([0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6]);
298
+ const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
299
+ const cipher = factory.createCipher({
300
+ isCipher: isWrap,
301
+ cipherType,
302
+ cipherKey,
303
+ iv: defaultWrapIV.buffer // RFC 3394 default IV for AES-KW
304
+ });
305
+
306
+ // Process data
307
+ const updated = cipher.update(data);
308
+ const final = cipher.final();
309
+
310
+ // Concatenate results
311
+ const result = new Uint8Array(updated.byteLength + final.byteLength);
312
+ result.set(new Uint8Array(updated), 0);
313
+ result.set(new Uint8Array(final), updated.byteLength);
314
+ return result.buffer;
315
+ }
316
+ async function chaCha20Poly1305Cipher(mode, key, data, algorithm) {
317
+ const {
318
+ iv,
319
+ additionalData,
320
+ tagLength = 128
321
+ } = algorithm;
322
+
323
+ // Validate IV (must be 12 bytes for ChaCha20-Poly1305)
324
+ const ivBuffer = (0, _conversion.bufferLikeToArrayBuffer)(iv);
325
+ if (!ivBuffer || ivBuffer.byteLength !== 12) {
326
+ throw (0, _errors.lazyDOMException)('ChaCha20-Poly1305 IV must be exactly 12 bytes', 'OperationError');
327
+ }
328
+
329
+ // Validate tag length (only 128-bit supported)
330
+ if (tagLength !== 128) {
331
+ throw (0, _errors.lazyDOMException)('ChaCha20-Poly1305 only supports 128-bit auth tags', 'NotSupportedError');
332
+ }
333
+ const tagByteLength = 16; // 128 bits = 16 bytes
334
+
335
+ // Create cipher using existing ChaCha20-Poly1305 implementation
336
+ const factory = _reactNativeNitroModules.NitroModules.createHybridObject('CipherFactory');
337
+ const cipher = factory.createCipher({
338
+ isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
339
+ cipherType: 'chacha20-poly1305',
340
+ cipherKey: (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.export()),
341
+ iv: ivBuffer,
342
+ authTagLen: tagByteLength
343
+ });
344
+ let processData;
345
+ let authTag;
346
+ if (mode === CipherOrWrapMode.kWebCryptoCipherDecrypt) {
347
+ // For decryption, extract auth tag from end of data
348
+ const dataView = new Uint8Array(data);
349
+ if (dataView.byteLength < tagByteLength) {
350
+ throw (0, _errors.lazyDOMException)('The provided data is too small.', 'OperationError');
351
+ }
352
+
353
+ // Split data and tag
354
+ const ciphertextLength = dataView.byteLength - tagByteLength;
355
+ processData = dataView.slice(0, ciphertextLength).buffer;
356
+ authTag = dataView.slice(ciphertextLength).buffer;
357
+
358
+ // Set auth tag for verification
359
+ cipher.setAuthTag(authTag);
360
+ } else {
361
+ processData = data;
362
+ }
363
+
364
+ // Set additional authenticated data if provided
365
+ if (additionalData) {
366
+ cipher.setAAD((0, _conversion.bufferLikeToArrayBuffer)(additionalData));
367
+ }
368
+
369
+ // Process data
370
+ const updated = cipher.update(processData);
371
+ const final = cipher.final();
372
+ if (mode === CipherOrWrapMode.kWebCryptoCipherEncrypt) {
373
+ // For encryption, append auth tag to result
374
+ const tag = cipher.getAuthTag();
375
+ const result = new Uint8Array(updated.byteLength + final.byteLength + tag.byteLength);
376
+ result.set(new Uint8Array(updated), 0);
377
+ result.set(new Uint8Array(final), updated.byteLength);
378
+ result.set(new Uint8Array(tag), updated.byteLength + final.byteLength);
379
+ return result.buffer;
380
+ } else {
381
+ // For decryption, just concatenate plaintext
382
+ const result = new Uint8Array(updated.byteLength + final.byteLength);
383
+ result.set(new Uint8Array(updated), 0);
384
+ result.set(new Uint8Array(final), updated.byteLength);
385
+ return result.buffer;
386
+ }
387
+ }
274
388
  async function aesGenerateKey(algorithm, extractable, keyUsages) {
275
389
  const {
276
390
  length
@@ -558,7 +672,9 @@ function edImportKey(format, data, algorithm, extractable, keyUsages) {
558
672
  } = algorithm;
559
673
 
560
674
  // Validate usages
561
- if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
675
+ const isX = name === 'X25519' || name === 'X448';
676
+ const allowedUsages = isX ? ['deriveKey', 'deriveBits'] : ['sign', 'verify'];
677
+ if (hasAnyNotIn(keyUsages, allowedUsages)) {
562
678
  throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
563
679
  }
564
680
  let keyObject;
@@ -631,8 +747,12 @@ const exportKeySpki = async key => {
631
747
  case 'Ed25519':
632
748
  // Fall through
633
749
  case 'Ed448':
750
+ // Fall through
751
+ case 'X25519':
752
+ // Fall through
753
+ case 'X448':
634
754
  if (key.type === 'public') {
635
- // Export Ed key in SPKI DER format
755
+ // Export Ed/X key in SPKI DER format
636
756
  return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
637
757
  }
638
758
  break;
@@ -670,8 +790,12 @@ const exportKeyPkcs8 = async key => {
670
790
  case 'Ed25519':
671
791
  // Fall through
672
792
  case 'Ed448':
793
+ // Fall through
794
+ case 'X25519':
795
+ // Fall through
796
+ case 'X448':
673
797
  if (key.type === 'private') {
674
- // Export Ed key in PKCS8 DER format
798
+ // Export Ed/X key in PKCS8 DER format
675
799
  return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
676
800
  }
677
801
  break;
@@ -697,6 +821,19 @@ const exportKeyRaw = key => {
697
821
  return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatRaw);
698
822
  }
699
823
  break;
824
+ case 'Ed25519':
825
+ // Fall through
826
+ case 'Ed448':
827
+ // Fall through
828
+ case 'X25519':
829
+ // Fall through
830
+ case 'X448':
831
+ if (key.type === 'public') {
832
+ // Export raw public key
833
+ const exported = key.keyObject.handle.exportKey();
834
+ return (0, _conversion.bufferLikeToArrayBuffer)(exported);
835
+ }
836
+ break;
700
837
  case 'AES-CTR':
701
838
  // Fall through
702
839
  case 'AES-CBC':
@@ -705,6 +842,8 @@ const exportKeyRaw = key => {
705
842
  // Fall through
706
843
  case 'AES-KW':
707
844
  // Fall through
845
+ case 'ChaCha20-Poly1305':
846
+ // Fall through
708
847
  case 'HMAC':
709
848
  {
710
849
  const exported = key.keyObject.export();
@@ -744,6 +883,8 @@ const exportKeyJWK = key => {
744
883
  case 'AES-GCM':
745
884
  // Fall through
746
885
  case 'AES-KW':
886
+ // Fall through
887
+ case 'ChaCha20-Poly1305':
747
888
  if (key.algorithm.length === undefined) {
748
889
  throw (0, _errors.lazyDOMException)(`Algorithm ${key.algorithm.name} missing required length property`, 'InvalidAccessError');
749
890
  }
@@ -941,6 +1082,10 @@ const cipherOrWrap = async (mode, algorithm, key, data, op) => {
941
1082
  // Fall through
942
1083
  case 'AES-GCM':
943
1084
  return aesCipher(mode, key, data, algorithm);
1085
+ case 'AES-KW':
1086
+ return aesKwCipher(mode, key, data);
1087
+ case 'ChaCha20-Poly1305':
1088
+ return chaCha20Poly1305Cipher(mode, key, data, algorithm);
944
1089
  }
945
1090
  };
946
1091
  class Subtle {
@@ -953,16 +1098,49 @@ class Subtle {
953
1098
  return (0, _hash.asyncDigest)(normalizedAlgorithm, data);
954
1099
  }
955
1100
  async deriveBits(algorithm, baseKey, length) {
956
- if (!baseKey.keyUsages.includes('deriveBits')) {
957
- throw new Error('baseKey does not have deriveBits usage');
1101
+ // Allow either deriveBits OR deriveKey usage (WebCrypto spec allows both)
1102
+ if (!baseKey.keyUsages.includes('deriveBits') && !baseKey.keyUsages.includes('deriveKey')) {
1103
+ throw new Error('baseKey does not have deriveBits or deriveKey usage');
958
1104
  }
959
1105
  if (baseKey.algorithm.name !== algorithm.name) throw new Error('Key algorithm mismatch');
960
1106
  switch (algorithm.name) {
961
1107
  case 'PBKDF2':
962
1108
  return (0, _pbkdf.pbkdf2DeriveBits)(algorithm, baseKey, length);
1109
+ case 'X25519':
1110
+ // Fall through
1111
+ case 'X448':
1112
+ return (0, _ed.xDeriveBits)(algorithm, baseKey, length);
963
1113
  }
964
1114
  throw new Error(`'subtle.deriveBits()' for ${algorithm.name} is not implemented.`);
965
1115
  }
1116
+ async deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages) {
1117
+ // Validate baseKey usage
1118
+ if (!baseKey.usages.includes('deriveKey') && !baseKey.usages.includes('deriveBits')) {
1119
+ throw (0, _errors.lazyDOMException)('baseKey does not have deriveKey or deriveBits usage', 'InvalidAccessError');
1120
+ }
1121
+
1122
+ // Calculate required key length
1123
+ const length = getKeyLength(derivedKeyAlgorithm);
1124
+
1125
+ // Step 1: Derive bits
1126
+ let derivedBits;
1127
+ if (baseKey.algorithm.name !== algorithm.name) throw new Error('Key algorithm mismatch');
1128
+ switch (algorithm.name) {
1129
+ case 'PBKDF2':
1130
+ derivedBits = await (0, _pbkdf.pbkdf2DeriveBits)(algorithm, baseKey, length);
1131
+ break;
1132
+ case 'X25519':
1133
+ // Fall through
1134
+ case 'X448':
1135
+ derivedBits = await (0, _ed.xDeriveBits)(algorithm, baseKey, length);
1136
+ break;
1137
+ default:
1138
+ throw new Error(`'subtle.deriveKey()' for ${algorithm.name} is not implemented.`);
1139
+ }
1140
+
1141
+ // Step 2: Import as key
1142
+ return this.importKey('raw', derivedBits, derivedKeyAlgorithm, extractable, keyUsages);
1143
+ }
966
1144
  async encrypt(algorithm, key, data) {
967
1145
  const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'encrypt');
968
1146
  return cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherEncrypt, normalizedAlgorithm, key, (0, _conversion.bufferLikeToArrayBuffer)(data), 'encrypt');
@@ -980,6 +1158,76 @@ class Subtle {
980
1158
  return exportKeyRaw(key);
981
1159
  }
982
1160
  }
1161
+ async wrapKey(format, key, wrappingKey, wrapAlgorithm) {
1162
+ // Validate wrappingKey usage
1163
+ if (!wrappingKey.usages.includes('wrapKey')) {
1164
+ throw (0, _errors.lazyDOMException)('wrappingKey does not have wrapKey usage', 'InvalidAccessError');
1165
+ }
1166
+
1167
+ // Step 1: Export the key
1168
+ const exported = await this.exportKey(format, key);
1169
+
1170
+ // Step 2: Convert to ArrayBuffer if JWK
1171
+ let keyData;
1172
+ if (format === 'jwk') {
1173
+ const jwkString = JSON.stringify(exported);
1174
+ const buffer = _safeBuffer.Buffer.from(jwkString, 'utf8');
1175
+
1176
+ // For AES-KW, pad to multiple of 8 bytes (accounting for null terminator)
1177
+ if (wrapAlgorithm.name === 'AES-KW') {
1178
+ const length = buffer.length;
1179
+ // Add 1 for null terminator, then pad to multiple of 8
1180
+ const paddedLength = Math.ceil((length + 1) / 8) * 8;
1181
+ const paddedBuffer = _safeBuffer.Buffer.alloc(paddedLength);
1182
+ buffer.copy(paddedBuffer);
1183
+ // Null terminator for JSON string (remaining bytes are already zeros from alloc)
1184
+ paddedBuffer.writeUInt8(0, length);
1185
+ keyData = (0, _conversion.bufferLikeToArrayBuffer)(paddedBuffer);
1186
+ } else {
1187
+ keyData = (0, _conversion.bufferLikeToArrayBuffer)(buffer);
1188
+ }
1189
+ } else {
1190
+ keyData = exported;
1191
+ }
1192
+
1193
+ // Step 3: Encrypt the exported key
1194
+ return cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherEncrypt, wrapAlgorithm, wrappingKey, keyData, 'wrapKey');
1195
+ }
1196
+ async unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) {
1197
+ // Validate unwrappingKey usage
1198
+ if (!unwrappingKey.usages.includes('unwrapKey')) {
1199
+ throw (0, _errors.lazyDOMException)('unwrappingKey does not have unwrapKey usage', 'InvalidAccessError');
1200
+ }
1201
+
1202
+ // Step 1: Decrypt the wrapped key
1203
+ const decrypted = await cipherOrWrap(CipherOrWrapMode.kWebCryptoCipherDecrypt, unwrapAlgorithm, unwrappingKey, (0, _conversion.bufferLikeToArrayBuffer)(wrappedKey), 'unwrapKey');
1204
+
1205
+ // Step 2: Convert to appropriate format
1206
+ let keyData;
1207
+ if (format === 'jwk') {
1208
+ const buffer = _safeBuffer.Buffer.from(decrypted);
1209
+ // For AES-KW, the data may be padded - find the null terminator
1210
+ let jwkString;
1211
+ if (unwrapAlgorithm.name === 'AES-KW') {
1212
+ // Find the null terminator (if present) to get the original string
1213
+ const nullIndex = buffer.indexOf(0);
1214
+ if (nullIndex !== -1) {
1215
+ jwkString = buffer.toString('utf8', 0, nullIndex);
1216
+ } else {
1217
+ // No null terminator, try to parse the whole buffer
1218
+ jwkString = buffer.toString('utf8').trim();
1219
+ }
1220
+ } else {
1221
+ jwkString = buffer.toString('utf8');
1222
+ }
1223
+ keyData = JSON.parse(jwkString);
1224
+ } else {
1225
+ keyData = decrypted;
1226
+ }
1227
+
1228
+ // Step 3: Import the key
1229
+ return this.importKey(format, keyData, unwrappedKeyAlgorithm, extractable, keyUsages);
1230
+ }
983
1231
  async generateKey(algorithm, extractable, keyUsages) {
984
1232
  algorithm = normalizeAlgorithm(algorithm, 'generateKey');
985
1233
  let result;
@@ -1006,6 +1254,18 @@ class Subtle {
1006
1254
  case 'AES-KW':
1007
1255
  result = await aesGenerateKey(algorithm, extractable, keyUsages);
1008
1256
  break;
1257
+ case 'ChaCha20-Poly1305':
1258
+ {
1259
+ const length = algorithm.length ?? 256;
1260
+ if (length !== 256) {
1261
+ throw (0, _errors.lazyDOMException)('ChaCha20-Poly1305 only supports 256-bit keys', 'NotSupportedError');
1262
+ }
1263
+ result = await aesGenerateKey({
1264
+ name: 'ChaCha20-Poly1305',
1265
+ length: 256
1266
+ }, extractable, keyUsages);
1267
+ break;
1268
+ }
1009
1269
  case 'HMAC':
1010
1270
  result = await hmacGenerateKey(algorithm, extractable, keyUsages);
1011
1271
  break;
@@ -1023,6 +1283,12 @@ class Subtle {
1023
1283
  result = await (0, _mldsa.mldsa_generateKeyPairWebCrypto)(algorithm.name, extractable, keyUsages);
1024
1284
  checkCryptoKeyPairUsages(result);
1025
1285
  break;
1286
+ case 'X25519':
1287
+ // Fall through
1288
+ case 'X448':
1289
+ result = await (0, _ed.x_generateKeyPairWebCrypto)(algorithm.name.toLowerCase(), extractable, keyUsages);
1290
+ checkCryptoKeyPairUsages(result);
1291
+ break;
1026
1292
  default:
1027
1293
  throw new Error(`'subtle.generateKey()' is not implemented for ${algorithm.name}.
1028
1294
  Unrecognized algorithm name`);
@@ -1055,11 +1321,17 @@ class Subtle {
1055
1321
  case 'AES-GCM':
1056
1322
  // Fall through
1057
1323
  case 'AES-KW':
1324
+ // Fall through
1325
+ case 'ChaCha20-Poly1305':
1058
1326
  result = await aesImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
1059
1327
  break;
1060
1328
  case 'PBKDF2':
1061
1329
  result = await importGenericSecretKey(normalizedAlgorithm, format, data, extractable, keyUsages);
1062
1330
  break;
1331
+ case 'X25519':
1332
+ // Fall through
1333
+ case 'X448':
1334
+ // Fall through
1063
1335
  case 'Ed25519':
1064
1336
  // Fall through
1065
1337
  case 'Ed448':
@@ -1081,12 +1353,105 @@ class Subtle {
1081
1353
  return result;
1082
1354
  }
1083
1355
  async sign(algorithm, key, data) {
1084
- return signVerify(algorithm, key, data);
1356
+ const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'sign');
1357
+ if (normalizedAlgorithm.name === 'HMAC') {
1358
+ // Validate key usage
1359
+ if (!key.usages.includes('sign')) {
1360
+ throw (0, _errors.lazyDOMException)('Key does not have sign usage', 'InvalidAccessError');
1361
+ }
1362
+
1363
+ // Get hash algorithm from key or algorithm params
1364
+ // Hash can be either a string or an object with name property
1365
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1366
+ const alg = normalizedAlgorithm;
1367
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1368
+ const keyAlg = key.algorithm;
1369
+ let hashAlgorithm = 'SHA-256';
1370
+ if (typeof alg.hash === 'string') {
1371
+ hashAlgorithm = alg.hash;
1372
+ } else if (alg.hash?.name) {
1373
+ hashAlgorithm = alg.hash.name;
1374
+ } else if (typeof keyAlg.hash === 'string') {
1375
+ hashAlgorithm = keyAlg.hash;
1376
+ } else if (keyAlg.hash?.name) {
1377
+ hashAlgorithm = keyAlg.hash.name;
1378
+ }
1379
+
1380
+ // Create HMAC and sign
1381
+ const keyData = key.keyObject.export();
1382
+ const hmac = (0, _hmac.createHmac)(hashAlgorithm, keyData);
1383
+ hmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
1384
+ return (0, _conversion.bufferLikeToArrayBuffer)(hmac.digest());
1385
+ }
1386
+ return signVerify(normalizedAlgorithm, key, data);
1085
1387
  }
1086
1388
  async verify(algorithm, key, signature, data) {
1087
- return signVerify(algorithm, key, data, signature);
1389
+ const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'verify');
1390
+ if (normalizedAlgorithm.name === 'HMAC') {
1391
+ // Validate key usage
1392
+ if (!key.usages.includes('verify')) {
1393
+ throw (0, _errors.lazyDOMException)('Key does not have verify usage', 'InvalidAccessError');
1394
+ }
1395
+
1396
+ // Get hash algorithm
1397
+ // Hash can be either a string or an object with name property
1398
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1399
+ const alg = normalizedAlgorithm;
1400
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1401
+ const keyAlg = key.algorithm;
1402
+ let hashAlgorithm = 'SHA-256';
1403
+ if (typeof alg.hash === 'string') {
1404
+ hashAlgorithm = alg.hash;
1405
+ } else if (alg.hash?.name) {
1406
+ hashAlgorithm = alg.hash.name;
1407
+ } else if (typeof keyAlg.hash === 'string') {
1408
+ hashAlgorithm = keyAlg.hash;
1409
+ } else if (keyAlg.hash?.name) {
1410
+ hashAlgorithm = keyAlg.hash.name;
1411
+ }
1412
+
1413
+ // Create HMAC and compute expected signature
1414
+ const keyData = key.keyObject.export();
1415
+ const hmac = (0, _hmac.createHmac)(hashAlgorithm, keyData);
1416
+ const dataBuffer = (0, _conversion.bufferLikeToArrayBuffer)(data);
1417
+ hmac.update(dataBuffer);
1418
+ const expectedDigest = hmac.digest();
1419
+ const expected = new Uint8Array((0, _conversion.bufferLikeToArrayBuffer)(expectedDigest));
1420
+
1421
+ // Constant-time comparison
1422
+ const signatureArray = new Uint8Array((0, _conversion.bufferLikeToArrayBuffer)(signature));
1423
+ if (expected.length !== signatureArray.length) {
1424
+ return false;
1425
+ }
1426
+
1427
+ // Manual constant-time comparison
1428
+ let result = 0;
1429
+ for (let i = 0; i < expected.length; i++) {
1430
+ result |= expected[i] ^ signatureArray[i];
1431
+ }
1432
+ return result === 0;
1433
+ }
1434
+ return signVerify(normalizedAlgorithm, key, data, signature);
1088
1435
  }
1089
1436
  }
1090
1437
  exports.Subtle = Subtle;
1091
1438
  const subtle = exports.subtle = new Subtle();
1439
+ function getKeyLength(algorithm) {
1440
+ const name = algorithm.name;
1441
+ switch (name) {
1442
+ case 'AES-CTR':
1443
+ case 'AES-CBC':
1444
+ case 'AES-GCM':
1445
+ case 'AES-KW':
1446
+ case 'ChaCha20-Poly1305':
1447
+ return algorithm.length || 256;
1448
+ case 'HMAC':
1449
+ {
1450
+ const hmacAlg = algorithm;
1451
+ return hmacAlg.length || 256;
1452
+ }
1453
+ default:
1454
+ throw (0, _errors.lazyDOMException)(`Cannot determine key length for ${name}`, 'NotSupportedError');
1455
+ }
1456
+ }
1092
1457
  //# sourceMappingURL=subtle.js.map