react-native-quick-crypto 1.0.11 → 1.0.12
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/android/CMakeLists.txt +7 -0
- package/cpp/cipher/CCMCipher.cpp +4 -1
- package/cpp/cipher/ChaCha20Cipher.cpp +3 -1
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +5 -5
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/HybridCipher.cpp +10 -1
- package/cpp/cipher/HybridCipher.hpp +2 -0
- package/cpp/cipher/HybridRsaCipher.cpp +0 -13
- package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +1 -2
- package/cpp/cipher/XSalsa20Cipher.cpp +4 -0
- package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +7 -5
- package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +1 -2
- package/cpp/ecdh/HybridECDH.cpp +20 -133
- package/cpp/keys/HybridKeyObjectHandle.cpp +144 -141
- package/cpp/keys/HybridKeyObjectHandle.hpp +6 -3
- package/cpp/keys/KeyObjectData.hpp +2 -0
- package/cpp/kmac/HybridKmac.cpp +83 -0
- package/cpp/kmac/HybridKmac.hpp +31 -0
- package/cpp/mldsa/HybridMlDsaKeyPair.cpp +11 -20
- package/cpp/mldsa/HybridMlDsaKeyPair.hpp +4 -2
- package/cpp/mlkem/HybridMlKemKeyPair.cpp +319 -0
- package/cpp/mlkem/HybridMlKemKeyPair.hpp +48 -0
- package/cpp/sign/SignUtils.hpp +9 -26
- package/cpp/utils/QuickCryptoUtils.cpp +44 -0
- package/cpp/utils/QuickCryptoUtils.hpp +39 -0
- package/cpp/x509/HybridX509Certificate.cpp +174 -0
- package/cpp/x509/HybridX509Certificate.hpp +51 -0
- package/lib/commonjs/cipher.js +15 -2
- package/lib/commonjs/cipher.js.map +1 -1
- package/lib/commonjs/dhKeyPair.js +3 -3
- package/lib/commonjs/dhKeyPair.js.map +1 -1
- package/lib/commonjs/dsa.js +3 -3
- package/lib/commonjs/dsa.js.map +1 -1
- package/lib/commonjs/ec.js +18 -18
- package/lib/commonjs/ec.js.map +1 -1
- package/lib/commonjs/ed.js +9 -9
- package/lib/commonjs/ed.js.map +1 -1
- package/lib/commonjs/hash.js +17 -12
- package/lib/commonjs/hash.js.map +1 -1
- package/lib/commonjs/hkdf.js.map +1 -1
- package/lib/commonjs/index.js +22 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +2 -2
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/index.js +24 -0
- package/lib/commonjs/keys/index.js.map +1 -1
- package/lib/commonjs/keys/signVerify.js +0 -2
- package/lib/commonjs/keys/signVerify.js.map +1 -1
- package/lib/commonjs/mlkem.js +219 -0
- package/lib/commonjs/mlkem.js.map +1 -0
- package/lib/commonjs/pbkdf2.js +18 -1
- package/lib/commonjs/pbkdf2.js.map +1 -1
- package/lib/commonjs/rsa.js +7 -7
- package/lib/commonjs/rsa.js.map +1 -1
- package/lib/commonjs/specs/kmac.nitro.js +6 -0
- package/lib/commonjs/specs/kmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/x509certificate.nitro.js +6 -0
- package/lib/commonjs/specs/x509certificate.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +292 -112
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/commonjs/utils/conversion.js +3 -3
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/hashnames.js +31 -0
- package/lib/commonjs/utils/hashnames.js.map +1 -1
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/x509certificate.js +189 -0
- package/lib/commonjs/x509certificate.js.map +1 -0
- package/lib/module/cipher.js +16 -3
- package/lib/module/cipher.js.map +1 -1
- package/lib/module/dhKeyPair.js +1 -1
- package/lib/module/dhKeyPair.js.map +1 -1
- package/lib/module/dsa.js +1 -1
- package/lib/module/dsa.js.map +1 -1
- package/lib/module/ec.js +6 -6
- package/lib/module/ec.js.map +1 -1
- package/lib/module/ed.js +1 -1
- package/lib/module/ed.js.map +1 -1
- package/lib/module/hash.js +17 -12
- package/lib/module/hash.js.map +1 -1
- package/lib/module/hkdf.js.map +1 -1
- package/lib/module/index.js +6 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +2 -2
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/index.js +25 -1
- package/lib/module/keys/index.js.map +1 -1
- package/lib/module/keys/signVerify.js +0 -2
- package/lib/module/keys/signVerify.js.map +1 -1
- package/lib/module/mlkem.js +211 -0
- package/lib/module/mlkem.js.map +1 -0
- package/lib/module/pbkdf2.js +18 -1
- package/lib/module/pbkdf2.js.map +1 -1
- package/lib/module/rsa.js +1 -1
- package/lib/module/rsa.js.map +1 -1
- package/lib/module/specs/kmac.nitro.js +4 -0
- package/lib/module/specs/kmac.nitro.js.map +1 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js +4 -0
- package/lib/module/specs/mlKemKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/x509certificate.nitro.js +4 -0
- package/lib/module/specs/x509certificate.nitro.js.map +1 -0
- package/lib/module/subtle.js +292 -112
- package/lib/module/subtle.js.map +1 -1
- package/lib/module/utils/conversion.js +3 -4
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/hashnames.js +31 -0
- package/lib/module/utils/hashnames.js.map +1 -1
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/x509certificate.js +184 -0
- package/lib/module/x509certificate.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/cipher.d.ts +3 -0
- package/lib/typescript/cipher.d.ts.map +1 -1
- package/lib/typescript/dhKeyPair.d.ts +1 -1
- package/lib/typescript/dhKeyPair.d.ts.map +1 -1
- package/lib/typescript/dsa.d.ts +1 -1
- package/lib/typescript/dsa.d.ts.map +1 -1
- package/lib/typescript/ec.d.ts +1 -1
- package/lib/typescript/ec.d.ts.map +1 -1
- package/lib/typescript/ed.d.ts +1 -1
- package/lib/typescript/ed.d.ts.map +1 -1
- package/lib/typescript/hash.d.ts.map +1 -1
- package/lib/typescript/hkdf.d.ts +2 -6
- package/lib/typescript/hkdf.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +15 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +5 -5
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/index.d.ts +2 -2
- package/lib/typescript/keys/index.d.ts.map +1 -1
- package/lib/typescript/keys/signVerify.d.ts.map +1 -1
- package/lib/typescript/mlkem.d.ts +30 -0
- package/lib/typescript/mlkem.d.ts.map +1 -0
- package/lib/typescript/pbkdf2.d.ts +2 -2
- package/lib/typescript/pbkdf2.d.ts.map +1 -1
- package/lib/typescript/rsa.d.ts +1 -1
- package/lib/typescript/rsa.d.ts.map +1 -1
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/kmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/kmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts +18 -0
- package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts +34 -0
- package/lib/typescript/specs/x509certificate.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +10 -0
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/hashnames.d.ts +1 -1
- package/lib/typescript/utils/hashnames.d.ts.map +1 -1
- package/lib/typescript/utils/types.d.ts +13 -7
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/x509certificate.d.ts +64 -0
- package/lib/typescript/x509certificate.d.ts.map +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +3 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +30 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +30 -0
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +12 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +1 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridKmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.hpp +74 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.cpp +46 -0
- package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.hpp +96 -0
- package/package.json +4 -1
- package/src/cipher.ts +17 -3
- package/src/dhKeyPair.ts +1 -1
- package/src/dsa.ts +1 -1
- package/src/ec.ts +9 -9
- package/src/ed.ts +2 -2
- package/src/hash.ts +34 -11
- package/src/hkdf.ts +2 -7
- package/src/index.ts +7 -0
- package/src/keys/classes.ts +10 -9
- package/src/keys/index.ts +37 -2
- package/src/keys/signVerify.ts +0 -5
- package/src/mlkem.ts +350 -0
- package/src/pbkdf2.ts +34 -5
- package/src/rsa.ts +1 -1
- package/src/specs/keyObjectHandle.nitro.ts +5 -0
- package/src/specs/kmac.nitro.ts +12 -0
- package/src/specs/mlKemKeyPair.nitro.ts +32 -0
- package/src/specs/x509certificate.nitro.ts +38 -0
- package/src/subtle.ts +551 -125
- package/src/utils/conversion.ts +10 -4
- package/src/utils/hashnames.ts +33 -2
- package/src/utils/types.ts +42 -5
- package/src/x509certificate.ts +277 -0
package/lib/commonjs/subtle.js
CHANGED
|
@@ -21,9 +21,11 @@ var _ec = require("./ec");
|
|
|
21
21
|
var _rsa = require("./rsa");
|
|
22
22
|
var _random = require("./random");
|
|
23
23
|
var _hmac = require("./hmac");
|
|
24
|
+
var _timingSafeEqual = require("./utils/timingSafeEqual");
|
|
24
25
|
var _signVerify = require("./keys/signVerify");
|
|
25
26
|
var _ed = require("./ed");
|
|
26
27
|
var _mldsa = require("./mldsa");
|
|
28
|
+
var _mlkem = require("./mlkem");
|
|
27
29
|
var _hkdf = require("./hkdf");
|
|
28
30
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
29
31
|
// Temporary enums that need to be defined
|
|
@@ -488,6 +490,100 @@ async function hmacGenerateKey(algorithm, extractable, keyUsages) {
|
|
|
488
490
|
};
|
|
489
491
|
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
490
492
|
}
|
|
493
|
+
async function kmacGenerateKey(algorithm, extractable, keyUsages) {
|
|
494
|
+
const {
|
|
495
|
+
name
|
|
496
|
+
} = algorithm;
|
|
497
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
498
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
499
|
+
}
|
|
500
|
+
const defaultLength = name === 'KMAC128' ? 128 : 256;
|
|
501
|
+
const length = algorithm.length ?? defaultLength;
|
|
502
|
+
if (length === 0) {
|
|
503
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'OperationError');
|
|
504
|
+
}
|
|
505
|
+
const keyBytes = new Uint8Array(Math.ceil(length / 8));
|
|
506
|
+
(0, _random.getRandomValues)(keyBytes);
|
|
507
|
+
const keyObject = (0, _keys.createSecretKey)(keyBytes);
|
|
508
|
+
const keyAlgorithm = {
|
|
509
|
+
name: name,
|
|
510
|
+
length
|
|
511
|
+
};
|
|
512
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
513
|
+
}
|
|
514
|
+
function kmacSignVerify(key, data, algorithm, signature) {
|
|
515
|
+
const {
|
|
516
|
+
name
|
|
517
|
+
} = algorithm;
|
|
518
|
+
const defaultLength = name === 'KMAC128' ? 256 : 512;
|
|
519
|
+
const outputLengthBits = algorithm.length ?? defaultLength;
|
|
520
|
+
if (outputLengthBits % 8 !== 0) {
|
|
521
|
+
throw (0, _errors.lazyDOMException)('KMAC output length must be a multiple of 8', 'OperationError');
|
|
522
|
+
}
|
|
523
|
+
const outputLengthBytes = outputLengthBits / 8;
|
|
524
|
+
const keyData = key.keyObject.export();
|
|
525
|
+
const kmac = _reactNativeNitroModules.NitroModules.createHybridObject('Kmac');
|
|
526
|
+
let customizationBuffer;
|
|
527
|
+
if (algorithm.customization !== undefined) {
|
|
528
|
+
customizationBuffer = (0, _conversion.bufferLikeToArrayBuffer)(algorithm.customization);
|
|
529
|
+
}
|
|
530
|
+
kmac.createKmac(name, (0, _conversion.bufferLikeToArrayBuffer)(keyData), outputLengthBytes, customizationBuffer);
|
|
531
|
+
kmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
532
|
+
const computed = kmac.digest();
|
|
533
|
+
if (signature === undefined) {
|
|
534
|
+
return computed;
|
|
535
|
+
}
|
|
536
|
+
const sigBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
537
|
+
if (computed.byteLength !== sigBuffer.byteLength) {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
return (0, _timingSafeEqual.timingSafeEqual)(new Uint8Array(computed), new Uint8Array(sigBuffer));
|
|
541
|
+
}
|
|
542
|
+
async function kmacImportKey(algorithm, format, data, extractable, keyUsages) {
|
|
543
|
+
const {
|
|
544
|
+
name
|
|
545
|
+
} = algorithm;
|
|
546
|
+
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
547
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
548
|
+
}
|
|
549
|
+
let keyObject;
|
|
550
|
+
if (format === 'jwk') {
|
|
551
|
+
const jwk = data;
|
|
552
|
+
if (!jwk || typeof jwk !== 'object') {
|
|
553
|
+
throw (0, _errors.lazyDOMException)('Invalid keyData', 'DataError');
|
|
554
|
+
}
|
|
555
|
+
if (jwk.kty !== 'oct') {
|
|
556
|
+
throw (0, _errors.lazyDOMException)('Invalid JWK format for KMAC key', 'DataError');
|
|
557
|
+
}
|
|
558
|
+
const expectedAlg = name === 'KMAC128' ? 'K128' : 'K256';
|
|
559
|
+
if (jwk.alg !== undefined && jwk.alg !== expectedAlg) {
|
|
560
|
+
throw (0, _errors.lazyDOMException)('JWK "alg" does not match the requested algorithm', 'DataError');
|
|
561
|
+
}
|
|
562
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
563
|
+
const keyType = handle.initJwk(jwk, undefined);
|
|
564
|
+
if (keyType === undefined || keyType !== 0) {
|
|
565
|
+
throw (0, _errors.lazyDOMException)('Failed to import KMAC JWK', 'DataError');
|
|
566
|
+
}
|
|
567
|
+
keyObject = new _keys.SecretKeyObject(handle);
|
|
568
|
+
} else if (format === 'raw' || format === 'raw-secret') {
|
|
569
|
+
keyObject = (0, _keys.createSecretKey)(data);
|
|
570
|
+
} else {
|
|
571
|
+
throw (0, _errors.lazyDOMException)(`Unable to import ${name} key with format ${format}`, 'NotSupportedError');
|
|
572
|
+
}
|
|
573
|
+
const exported = keyObject.export();
|
|
574
|
+
const keyLength = exported.byteLength * 8;
|
|
575
|
+
if (keyLength === 0) {
|
|
576
|
+
throw (0, _errors.lazyDOMException)('Zero-length key is not supported', 'DataError');
|
|
577
|
+
}
|
|
578
|
+
if (algorithm.length !== undefined && algorithm.length !== keyLength) {
|
|
579
|
+
throw (0, _errors.lazyDOMException)('Invalid key length', 'DataError');
|
|
580
|
+
}
|
|
581
|
+
const keyAlgorithm = {
|
|
582
|
+
name: name,
|
|
583
|
+
length: keyLength
|
|
584
|
+
};
|
|
585
|
+
return new _keys.CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
|
|
586
|
+
}
|
|
491
587
|
function rsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
492
588
|
const {
|
|
493
589
|
name
|
|
@@ -725,28 +821,48 @@ function edImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
|
725
821
|
name
|
|
726
822
|
}, keyUsages, extractable);
|
|
727
823
|
}
|
|
824
|
+
function pqcImportKeyObject(format, data, name) {
|
|
825
|
+
if (format === 'spki') {
|
|
826
|
+
return _keys.KeyObject.createKeyObject('public', (0, _conversion.bufferLikeToArrayBuffer)(data), _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
827
|
+
} else if (format === 'pkcs8') {
|
|
828
|
+
return _keys.KeyObject.createKeyObject('private', (0, _conversion.bufferLikeToArrayBuffer)(data), _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
829
|
+
} else if (format === 'raw') {
|
|
830
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
831
|
+
if (!handle.initPqcRaw(name, (0, _conversion.bufferLikeToArrayBuffer)(data), true)) {
|
|
832
|
+
throw (0, _errors.lazyDOMException)(`Failed to import ${name} raw public key`, 'DataError');
|
|
833
|
+
}
|
|
834
|
+
return new _keys.PublicKeyObject(handle);
|
|
835
|
+
} else if (format === 'raw-seed') {
|
|
836
|
+
const handle = _reactNativeNitroModules.NitroModules.createHybridObject('KeyObjectHandle');
|
|
837
|
+
if (!handle.initPqcRaw(name, (0, _conversion.bufferLikeToArrayBuffer)(data), false)) {
|
|
838
|
+
throw (0, _errors.lazyDOMException)(`Failed to import ${name} raw seed`, 'DataError');
|
|
839
|
+
}
|
|
840
|
+
return new _keys.PrivateKeyObject(handle);
|
|
841
|
+
}
|
|
842
|
+
throw (0, _errors.lazyDOMException)(`Unsupported format for ${name} import: ${format}`, 'NotSupportedError');
|
|
843
|
+
}
|
|
728
844
|
function mldsaImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
729
845
|
const {
|
|
730
846
|
name
|
|
731
847
|
} = algorithm;
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
|
|
848
|
+
const isPublicFormat = format === 'spki' || format === 'raw';
|
|
849
|
+
if (hasAnyNotIn(keyUsages, isPublicFormat ? ['verify'] : ['sign'])) {
|
|
735
850
|
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
736
851
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
852
|
+
return new _keys.CryptoKey(pqcImportKeyObject(format, data, name), {
|
|
853
|
+
name
|
|
854
|
+
}, keyUsages, extractable);
|
|
855
|
+
}
|
|
856
|
+
function mlkemImportKey(format, data, algorithm, extractable, keyUsages) {
|
|
857
|
+
const {
|
|
858
|
+
name
|
|
859
|
+
} = algorithm;
|
|
860
|
+
const isPublicFormat = format === 'spki' || format === 'raw';
|
|
861
|
+
const allowedUsages = isPublicFormat ? ['encapsulateBits', 'encapsulateKey'] : ['decapsulateBits', 'decapsulateKey'];
|
|
862
|
+
if (hasAnyNotIn(keyUsages, allowedUsages)) {
|
|
863
|
+
throw (0, _errors.lazyDOMException)(`Unsupported key usage for ${name} key`, 'SyntaxError');
|
|
748
864
|
}
|
|
749
|
-
return new _keys.CryptoKey(
|
|
865
|
+
return new _keys.CryptoKey(pqcImportKeyObject(format, data, name), {
|
|
750
866
|
name
|
|
751
867
|
}, keyUsages, extractable);
|
|
752
868
|
}
|
|
@@ -790,6 +906,15 @@ const exportKeySpki = async key => {
|
|
|
790
906
|
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
791
907
|
}
|
|
792
908
|
break;
|
|
909
|
+
case 'ML-KEM-512':
|
|
910
|
+
// Fall through
|
|
911
|
+
case 'ML-KEM-768':
|
|
912
|
+
// Fall through
|
|
913
|
+
case 'ML-KEM-1024':
|
|
914
|
+
if (key.type === 'public') {
|
|
915
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI));
|
|
916
|
+
}
|
|
917
|
+
break;
|
|
793
918
|
}
|
|
794
919
|
throw new Error(`Unable to export a spki ${key.algorithm.name} ${key.type} key`);
|
|
795
920
|
};
|
|
@@ -833,6 +958,15 @@ const exportKeyPkcs8 = async key => {
|
|
|
833
958
|
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
834
959
|
}
|
|
835
960
|
break;
|
|
961
|
+
case 'ML-KEM-512':
|
|
962
|
+
// Fall through
|
|
963
|
+
case 'ML-KEM-768':
|
|
964
|
+
// Fall through
|
|
965
|
+
case 'ML-KEM-1024':
|
|
966
|
+
if (key.type === 'private') {
|
|
967
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8));
|
|
968
|
+
}
|
|
969
|
+
break;
|
|
836
970
|
}
|
|
837
971
|
throw new Error(`Unable to export a pkcs8 ${key.algorithm.name} ${key.type} key`);
|
|
838
972
|
};
|
|
@@ -853,7 +987,22 @@ const exportKeyRaw = key => {
|
|
|
853
987
|
// Fall through
|
|
854
988
|
case 'X448':
|
|
855
989
|
if (key.type === 'public') {
|
|
856
|
-
|
|
990
|
+
const exported = key.keyObject.handle.exportKey();
|
|
991
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
992
|
+
}
|
|
993
|
+
break;
|
|
994
|
+
case 'ML-KEM-512':
|
|
995
|
+
// Fall through
|
|
996
|
+
case 'ML-KEM-768':
|
|
997
|
+
// Fall through
|
|
998
|
+
case 'ML-KEM-1024':
|
|
999
|
+
// Fall through
|
|
1000
|
+
case 'ML-DSA-44':
|
|
1001
|
+
// Fall through
|
|
1002
|
+
case 'ML-DSA-65':
|
|
1003
|
+
// Fall through
|
|
1004
|
+
case 'ML-DSA-87':
|
|
1005
|
+
if (key.type === 'public') {
|
|
857
1006
|
const exported = key.keyObject.handle.exportKey();
|
|
858
1007
|
return (0, _conversion.bufferLikeToArrayBuffer)(exported);
|
|
859
1008
|
}
|
|
@@ -871,6 +1020,10 @@ const exportKeyRaw = key => {
|
|
|
871
1020
|
case 'ChaCha20-Poly1305':
|
|
872
1021
|
// Fall through
|
|
873
1022
|
case 'HMAC':
|
|
1023
|
+
// Fall through
|
|
1024
|
+
case 'KMAC128':
|
|
1025
|
+
// Fall through
|
|
1026
|
+
case 'KMAC256':
|
|
874
1027
|
{
|
|
875
1028
|
const exported = key.keyObject.export();
|
|
876
1029
|
// Convert Buffer to ArrayBuffer
|
|
@@ -897,6 +1050,12 @@ const exportKeyJWK = key => {
|
|
|
897
1050
|
case 'HMAC':
|
|
898
1051
|
jwk.alg = (0, _hashnames.normalizeHashName)(key.algorithm.hash, _hashnames.HashContext.JwkHmac);
|
|
899
1052
|
return jwk;
|
|
1053
|
+
case 'KMAC128':
|
|
1054
|
+
jwk.alg = 'K128';
|
|
1055
|
+
return jwk;
|
|
1056
|
+
case 'KMAC256':
|
|
1057
|
+
jwk.alg = 'K256';
|
|
1058
|
+
return jwk;
|
|
900
1059
|
case 'ECDSA':
|
|
901
1060
|
// Fall through
|
|
902
1061
|
case 'ECDH':
|
|
@@ -1035,20 +1194,12 @@ function hmacSignVerify(key, data, signature) {
|
|
|
1035
1194
|
// Sign operation - return the HMAC as ArrayBuffer
|
|
1036
1195
|
return computed.buffer.slice(computed.byteOffset, computed.byteOffset + computed.byteLength);
|
|
1037
1196
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
const computedBytes = new Uint8Array(computed.buffer, computed.byteOffset, computed.byteLength);
|
|
1042
|
-
if (computedBytes.length !== sigBytes.length) {
|
|
1197
|
+
const sigBuffer = (0, _conversion.bufferLikeToArrayBuffer)(signature);
|
|
1198
|
+
const computedBuffer = computed.buffer.slice(computed.byteOffset, computed.byteOffset + computed.byteLength);
|
|
1199
|
+
if (computedBuffer.byteLength !== sigBuffer.byteLength) {
|
|
1043
1200
|
return false;
|
|
1044
1201
|
}
|
|
1045
|
-
|
|
1046
|
-
// Constant-time comparison to prevent timing attacks
|
|
1047
|
-
let result = 0;
|
|
1048
|
-
for (let i = 0; i < computedBytes.length; i++) {
|
|
1049
|
-
result |= computedBytes[i] ^ sigBytes[i];
|
|
1050
|
-
}
|
|
1051
|
-
return result === 0;
|
|
1202
|
+
return (0, _timingSafeEqual.timingSafeEqual)(new Uint8Array(computedBuffer), new Uint8Array(sigBuffer));
|
|
1052
1203
|
}
|
|
1053
1204
|
function rsaSignVerify(key, data, padding, signature, saltLength) {
|
|
1054
1205
|
// Get hash algorithm from key
|
|
@@ -1151,6 +1302,9 @@ const signVerify = (algorithm, key, data, signature) => {
|
|
|
1151
1302
|
case 'ML-DSA-65':
|
|
1152
1303
|
case 'ML-DSA-87':
|
|
1153
1304
|
return mldsaSignVerify(key, data, signature);
|
|
1305
|
+
case 'KMAC128':
|
|
1306
|
+
case 'KMAC256':
|
|
1307
|
+
return kmacSignVerify(key, data, algorithm, signature);
|
|
1154
1308
|
}
|
|
1155
1309
|
throw (0, _errors.lazyDOMException)(`Unrecognized algorithm name '${algorithm.name}' for '${usage}'`, 'NotSupportedError');
|
|
1156
1310
|
};
|
|
@@ -1179,17 +1333,21 @@ const cipherOrWrap = async (mode, algorithm, key, data, op) => {
|
|
|
1179
1333
|
const SUPPORTED_ALGORITHMS = {
|
|
1180
1334
|
encrypt: new Set(['RSA-OAEP', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-OCB', 'ChaCha20-Poly1305']),
|
|
1181
1335
|
decrypt: new Set(['RSA-OAEP', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-OCB', 'ChaCha20-Poly1305']),
|
|
1182
|
-
sign: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1183
|
-
verify: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1184
|
-
digest: new Set(['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512']),
|
|
1185
|
-
generateKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1186
|
-
importKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'HKDF', 'PBKDF2', 'Argon2d', 'Argon2i', 'Argon2id', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1187
|
-
exportKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1336
|
+
sign: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'KMAC128', 'KMAC256', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1337
|
+
verify: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'ECDSA', 'HMAC', 'KMAC128', 'KMAC256', 'Ed25519', 'Ed448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']),
|
|
1338
|
+
digest: new Set(['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512', 'SHA3-256', 'SHA3-384', 'SHA3-512', 'cSHAKE128', 'cSHAKE256']),
|
|
1339
|
+
generateKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1340
|
+
importKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'HKDF', 'PBKDF2', 'Argon2d', 'Argon2i', 'Argon2id', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1341
|
+
exportKey: new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'HMAC', 'KMAC128', 'KMAC256', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1188
1342
|
deriveBits: new Set(['PBKDF2', 'HKDF', 'ECDH', 'X25519', 'X448', 'Argon2d', 'Argon2i', 'Argon2id']),
|
|
1189
1343
|
wrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP']),
|
|
1190
|
-
unwrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP'])
|
|
1344
|
+
unwrapKey: new Set(['AES-CTR', 'AES-CBC', 'AES-GCM', 'AES-KW', 'AES-OCB', 'ChaCha20-Poly1305', 'RSA-OAEP']),
|
|
1345
|
+
encapsulateBits: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1346
|
+
decapsulateBits: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1347
|
+
encapsulateKey: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']),
|
|
1348
|
+
decapsulateKey: new Set(['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024'])
|
|
1191
1349
|
};
|
|
1192
|
-
const ASYMMETRIC_ALGORITHMS = new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87']);
|
|
1350
|
+
const ASYMMETRIC_ALGORITHMS = new Set(['RSASSA-PKCS1-v1_5', 'RSA-PSS', 'RSA-OAEP', 'ECDSA', 'ECDH', 'Ed25519', 'Ed448', 'X25519', 'X448', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87', 'ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024']);
|
|
1193
1351
|
class Subtle {
|
|
1194
1352
|
static supports(operation, algorithm, _lengthOrAdditionalAlgorithm) {
|
|
1195
1353
|
let normalizedAlgorithm;
|
|
@@ -1296,6 +1454,18 @@ class Subtle {
|
|
|
1296
1454
|
}
|
|
1297
1455
|
async exportKey(format, key) {
|
|
1298
1456
|
if (!key.extractable) throw new Error('key is not extractable');
|
|
1457
|
+
if (format === 'raw-seed') {
|
|
1458
|
+
const pqcAlgos = ['ML-KEM-512', 'ML-KEM-768', 'ML-KEM-1024', 'ML-DSA-44', 'ML-DSA-65', 'ML-DSA-87'];
|
|
1459
|
+
if (!pqcAlgos.includes(key.algorithm.name)) {
|
|
1460
|
+
throw (0, _errors.lazyDOMException)('raw-seed export only supported for PQC keys', 'NotSupportedError');
|
|
1461
|
+
}
|
|
1462
|
+
if (key.type !== 'private') {
|
|
1463
|
+
throw (0, _errors.lazyDOMException)('raw-seed export requires a private key', 'InvalidAccessError');
|
|
1464
|
+
}
|
|
1465
|
+
return (0, _conversion.bufferLikeToArrayBuffer)(key.keyObject.handle.exportKey());
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
// Note: 'raw-seed' is handled above; do NOT normalize it here
|
|
1299
1469
|
if (format === 'raw-secret' || format === 'raw-public') format = 'raw';
|
|
1300
1470
|
switch (format) {
|
|
1301
1471
|
case 'spki':
|
|
@@ -1421,6 +1591,11 @@ class Subtle {
|
|
|
1421
1591
|
case 'HMAC':
|
|
1422
1592
|
result = await hmacGenerateKey(algorithm, extractable, keyUsages);
|
|
1423
1593
|
break;
|
|
1594
|
+
case 'KMAC128':
|
|
1595
|
+
// Fall through
|
|
1596
|
+
case 'KMAC256':
|
|
1597
|
+
result = await kmacGenerateKey(algorithm, extractable, keyUsages);
|
|
1598
|
+
break;
|
|
1424
1599
|
case 'Ed25519':
|
|
1425
1600
|
// Fall through
|
|
1426
1601
|
case 'Ed448':
|
|
@@ -1441,6 +1616,14 @@ class Subtle {
|
|
|
1441
1616
|
result = await (0, _ed.x_generateKeyPairWebCrypto)(algorithm.name.toLowerCase(), extractable, keyUsages);
|
|
1442
1617
|
checkCryptoKeyPairUsages(result);
|
|
1443
1618
|
break;
|
|
1619
|
+
case 'ML-KEM-512':
|
|
1620
|
+
// Fall through
|
|
1621
|
+
case 'ML-KEM-768':
|
|
1622
|
+
// Fall through
|
|
1623
|
+
case 'ML-KEM-1024':
|
|
1624
|
+
result = await (0, _mlkem.mlkem_generateKeyPairWebCrypto)(algorithm.name, extractable, keyUsages);
|
|
1625
|
+
checkCryptoKeyPairUsages(result);
|
|
1626
|
+
break;
|
|
1444
1627
|
default:
|
|
1445
1628
|
throw new Error(`'subtle.generateKey()' is not implemented for ${algorithm.name}.
|
|
1446
1629
|
Unrecognized algorithm name`);
|
|
@@ -1458,6 +1641,7 @@ class Subtle {
|
|
|
1458
1641
|
return publicKeyObject.toCryptoKey(key.algorithm, true, keyUsages);
|
|
1459
1642
|
}
|
|
1460
1643
|
async importKey(format, data, algorithm, extractable, keyUsages) {
|
|
1644
|
+
// Note: 'raw-seed' is NOT normalized — PQC import functions handle it directly
|
|
1461
1645
|
if (format === 'raw-secret' || format === 'raw-public') format = 'raw';
|
|
1462
1646
|
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'importKey');
|
|
1463
1647
|
let result;
|
|
@@ -1477,6 +1661,11 @@ class Subtle {
|
|
|
1477
1661
|
case 'HMAC':
|
|
1478
1662
|
result = await hmacImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
1479
1663
|
break;
|
|
1664
|
+
case 'KMAC128':
|
|
1665
|
+
// Fall through
|
|
1666
|
+
case 'KMAC256':
|
|
1667
|
+
result = await kmacImportKey(normalizedAlgorithm, format, data, extractable, keyUsages);
|
|
1668
|
+
break;
|
|
1480
1669
|
case 'AES-CTR':
|
|
1481
1670
|
// Fall through
|
|
1482
1671
|
case 'AES-CBC':
|
|
@@ -1515,6 +1704,13 @@ class Subtle {
|
|
|
1515
1704
|
case 'ML-DSA-87':
|
|
1516
1705
|
result = mldsaImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
1517
1706
|
break;
|
|
1707
|
+
case 'ML-KEM-512':
|
|
1708
|
+
// Fall through
|
|
1709
|
+
case 'ML-KEM-768':
|
|
1710
|
+
// Fall through
|
|
1711
|
+
case 'ML-KEM-1024':
|
|
1712
|
+
result = mlkemImportKey(format, data, normalizedAlgorithm, extractable, keyUsages);
|
|
1713
|
+
break;
|
|
1518
1714
|
default:
|
|
1519
1715
|
throw new Error(`"subtle.importKey()" is not implemented for ${normalizedAlgorithm.name}`);
|
|
1520
1716
|
}
|
|
@@ -1524,85 +1720,65 @@ class Subtle {
|
|
|
1524
1720
|
return result;
|
|
1525
1721
|
}
|
|
1526
1722
|
async sign(algorithm, key, data) {
|
|
1527
|
-
|
|
1528
|
-
if (normalizedAlgorithm.name === 'HMAC') {
|
|
1529
|
-
// Validate key usage
|
|
1530
|
-
if (!key.usages.includes('sign')) {
|
|
1531
|
-
throw (0, _errors.lazyDOMException)('Key does not have sign usage', 'InvalidAccessError');
|
|
1532
|
-
}
|
|
1533
|
-
|
|
1534
|
-
// Get hash algorithm from key or algorithm params
|
|
1535
|
-
// Hash can be either a string or an object with name property
|
|
1536
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1537
|
-
const alg = normalizedAlgorithm;
|
|
1538
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1539
|
-
const keyAlg = key.algorithm;
|
|
1540
|
-
let hashAlgorithm = 'SHA-256';
|
|
1541
|
-
if (typeof alg.hash === 'string') {
|
|
1542
|
-
hashAlgorithm = alg.hash;
|
|
1543
|
-
} else if (alg.hash?.name) {
|
|
1544
|
-
hashAlgorithm = alg.hash.name;
|
|
1545
|
-
} else if (typeof keyAlg.hash === 'string') {
|
|
1546
|
-
hashAlgorithm = keyAlg.hash;
|
|
1547
|
-
} else if (keyAlg.hash?.name) {
|
|
1548
|
-
hashAlgorithm = keyAlg.hash.name;
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
// Create HMAC and sign
|
|
1552
|
-
const keyData = key.keyObject.export();
|
|
1553
|
-
const hmac = (0, _hmac.createHmac)(hashAlgorithm, keyData);
|
|
1554
|
-
hmac.update((0, _conversion.bufferLikeToArrayBuffer)(data));
|
|
1555
|
-
return (0, _conversion.bufferLikeToArrayBuffer)(hmac.digest());
|
|
1556
|
-
}
|
|
1557
|
-
return signVerify(normalizedAlgorithm, key, data);
|
|
1723
|
+
return signVerify(normalizeAlgorithm(algorithm, 'sign'), key, data);
|
|
1558
1724
|
}
|
|
1559
1725
|
async verify(algorithm, key, signature, data) {
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
const dataBuffer = (0, _conversion.bufferLikeToArrayBuffer)(data);
|
|
1588
|
-
hmac.update(dataBuffer);
|
|
1589
|
-
const expectedDigest = hmac.digest();
|
|
1590
|
-
const expected = new Uint8Array((0, _conversion.bufferLikeToArrayBuffer)(expectedDigest));
|
|
1591
|
-
|
|
1592
|
-
// Constant-time comparison
|
|
1593
|
-
const signatureArray = new Uint8Array((0, _conversion.bufferLikeToArrayBuffer)(signature));
|
|
1594
|
-
if (expected.length !== signatureArray.length) {
|
|
1595
|
-
return false;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
// Manual constant-time comparison
|
|
1599
|
-
let result = 0;
|
|
1600
|
-
for (let i = 0; i < expected.length; i++) {
|
|
1601
|
-
result |= expected[i] ^ signatureArray[i];
|
|
1602
|
-
}
|
|
1603
|
-
return result === 0;
|
|
1726
|
+
return signVerify(normalizeAlgorithm(algorithm, 'verify'), key, data, signature);
|
|
1727
|
+
}
|
|
1728
|
+
_encapsulateCore(algorithm, key) {
|
|
1729
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'encapsulateBits');
|
|
1730
|
+
if (key.algorithm.name !== normalizedAlgorithm.name) {
|
|
1731
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
1732
|
+
}
|
|
1733
|
+
const variant = normalizedAlgorithm.name;
|
|
1734
|
+
const mlkem = new _mlkem.MlKem(variant);
|
|
1735
|
+
const keyData = key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
1736
|
+
mlkem.setPublicKey((0, _conversion.bufferLikeToArrayBuffer)(keyData), _utils.KFormatType.DER, _utils.KeyEncoding.SPKI);
|
|
1737
|
+
return mlkem.encapsulateSync();
|
|
1738
|
+
}
|
|
1739
|
+
_decapsulateCore(algorithm, key, ciphertext) {
|
|
1740
|
+
const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'decapsulateBits');
|
|
1741
|
+
if (key.algorithm.name !== normalizedAlgorithm.name) {
|
|
1742
|
+
throw (0, _errors.lazyDOMException)('Key algorithm mismatch', 'InvalidAccessError');
|
|
1743
|
+
}
|
|
1744
|
+
const variant = normalizedAlgorithm.name;
|
|
1745
|
+
const mlkem = new _mlkem.MlKem(variant);
|
|
1746
|
+
const keyData = key.keyObject.handle.exportKey(_utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
1747
|
+
mlkem.setPrivateKey((0, _conversion.bufferLikeToArrayBuffer)(keyData), _utils.KFormatType.DER, _utils.KeyEncoding.PKCS8);
|
|
1748
|
+
return mlkem.decapsulateSync((0, _conversion.bufferLikeToArrayBuffer)(ciphertext));
|
|
1749
|
+
}
|
|
1750
|
+
async encapsulateBits(algorithm, key) {
|
|
1751
|
+
if (!key.usages.includes('encapsulateBits')) {
|
|
1752
|
+
throw (0, _errors.lazyDOMException)('Key does not have encapsulateBits usage', 'InvalidAccessError');
|
|
1604
1753
|
}
|
|
1605
|
-
return
|
|
1754
|
+
return this._encapsulateCore(algorithm, key);
|
|
1755
|
+
}
|
|
1756
|
+
async encapsulateKey(algorithm, key, sharedKeyAlgorithm, extractable, usages) {
|
|
1757
|
+
if (!key.usages.includes('encapsulateKey')) {
|
|
1758
|
+
throw (0, _errors.lazyDOMException)('Key does not have encapsulateKey usage', 'InvalidAccessError');
|
|
1759
|
+
}
|
|
1760
|
+
const {
|
|
1761
|
+
sharedKey,
|
|
1762
|
+
ciphertext
|
|
1763
|
+
} = this._encapsulateCore(algorithm, key);
|
|
1764
|
+
const importedKey = await this.importKey('raw', sharedKey, sharedKeyAlgorithm, extractable, usages);
|
|
1765
|
+
return {
|
|
1766
|
+
key: importedKey,
|
|
1767
|
+
ciphertext
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
async decapsulateBits(algorithm, key, ciphertext) {
|
|
1771
|
+
if (!key.usages.includes('decapsulateBits')) {
|
|
1772
|
+
throw (0, _errors.lazyDOMException)('Key does not have decapsulateBits usage', 'InvalidAccessError');
|
|
1773
|
+
}
|
|
1774
|
+
return this._decapsulateCore(algorithm, key, ciphertext);
|
|
1775
|
+
}
|
|
1776
|
+
async decapsulateKey(algorithm, key, ciphertext, sharedKeyAlgorithm, extractable, usages) {
|
|
1777
|
+
if (!key.usages.includes('decapsulateKey')) {
|
|
1778
|
+
throw (0, _errors.lazyDOMException)('Key does not have decapsulateKey usage', 'InvalidAccessError');
|
|
1779
|
+
}
|
|
1780
|
+
const sharedKey = this._decapsulateCore(algorithm, key, ciphertext);
|
|
1781
|
+
return this.importKey('raw', sharedKey, sharedKeyAlgorithm, extractable, usages);
|
|
1606
1782
|
}
|
|
1607
1783
|
}
|
|
1608
1784
|
exports.Subtle = Subtle;
|
|
@@ -1622,6 +1798,10 @@ function getKeyLength(algorithm) {
|
|
|
1622
1798
|
const hmacAlg = algorithm;
|
|
1623
1799
|
return hmacAlg.length || 256;
|
|
1624
1800
|
}
|
|
1801
|
+
case 'KMAC128':
|
|
1802
|
+
return algorithm.length || 128;
|
|
1803
|
+
case 'KMAC256':
|
|
1804
|
+
return algorithm.length || 256;
|
|
1625
1805
|
default:
|
|
1626
1806
|
throw (0, _errors.lazyDOMException)(`Cannot determine key length for ${name}`, 'NotSupportedError');
|
|
1627
1807
|
}
|