@metamask-previews/passkey-controller 0.0.0-preview-4c0846313
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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +155 -0
- package/dist/PasskeyController.cjs +448 -0
- package/dist/PasskeyController.cjs.map +1 -0
- package/dist/PasskeyController.d.cts +168 -0
- package/dist/PasskeyController.d.cts.map +1 -0
- package/dist/PasskeyController.d.mts +168 -0
- package/dist/PasskeyController.d.mts.map +1 -0
- package/dist/PasskeyController.mjs +443 -0
- package/dist/PasskeyController.mjs.map +1 -0
- package/dist/ceremony-manager.cjs +134 -0
- package/dist/ceremony-manager.cjs.map +1 -0
- package/dist/ceremony-manager.d.cts +71 -0
- package/dist/ceremony-manager.d.cts.map +1 -0
- package/dist/ceremony-manager.d.mts +71 -0
- package/dist/ceremony-manager.d.mts.map +1 -0
- package/dist/ceremony-manager.mjs +130 -0
- package/dist/ceremony-manager.mjs.map +1 -0
- package/dist/constants.cjs +33 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +30 -0
- package/dist/constants.d.cts.map +1 -0
- package/dist/constants.d.mts +30 -0
- package/dist/constants.d.mts.map +1 -0
- package/dist/constants.mjs +30 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/errors.cjs +57 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +34 -0
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.mts +34 -0
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +53 -0
- package/dist/errors.mjs.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +9 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +5 -0
- package/dist/index.mjs.map +1 -0
- package/dist/key-derivation.cjs +76 -0
- package/dist/key-derivation.cjs.map +1 -0
- package/dist/key-derivation.d.cts +43 -0
- package/dist/key-derivation.d.cts.map +1 -0
- package/dist/key-derivation.d.mts +43 -0
- package/dist/key-derivation.d.mts.map +1 -0
- package/dist/key-derivation.mjs +71 -0
- package/dist/key-derivation.mjs.map +1 -0
- package/dist/logger.cjs +9 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +5 -0
- package/dist/logger.d.cts.map +1 -0
- package/dist/logger.d.mts +5 -0
- package/dist/logger.d.mts.map +1 -0
- package/dist/logger.mjs +6 -0
- package/dist/logger.mjs.map +1 -0
- package/dist/types.cjs +3 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +92 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +92 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +2 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils/crypto.cjs +55 -0
- package/dist/utils/crypto.cjs.map +1 -0
- package/dist/utils/crypto.d.cts +30 -0
- package/dist/utils/crypto.d.cts.map +1 -0
- package/dist/utils/crypto.d.mts +30 -0
- package/dist/utils/crypto.d.mts.map +1 -0
- package/dist/utils/crypto.mjs +49 -0
- package/dist/utils/crypto.mjs.map +1 -0
- package/dist/utils/encoding.cjs +42 -0
- package/dist/utils/encoding.cjs.map +1 -0
- package/dist/utils/encoding.d.cts +22 -0
- package/dist/utils/encoding.d.cts.map +1 -0
- package/dist/utils/encoding.d.mts +22 -0
- package/dist/utils/encoding.d.mts.map +1 -0
- package/dist/utils/encoding.mjs +36 -0
- package/dist/utils/encoding.mjs.map +1 -0
- package/dist/webauthn/constants.cjs +74 -0
- package/dist/webauthn/constants.cjs.map +1 -0
- package/dist/webauthn/constants.d.cts +68 -0
- package/dist/webauthn/constants.d.cts.map +1 -0
- package/dist/webauthn/constants.d.mts +68 -0
- package/dist/webauthn/constants.d.mts.map +1 -0
- package/dist/webauthn/constants.mjs +71 -0
- package/dist/webauthn/constants.mjs.map +1 -0
- package/dist/webauthn/decode-attestation-object.cjs +18 -0
- package/dist/webauthn/decode-attestation-object.cjs.map +1 -0
- package/dist/webauthn/decode-attestation-object.d.cts +10 -0
- package/dist/webauthn/decode-attestation-object.d.cts.map +1 -0
- package/dist/webauthn/decode-attestation-object.d.mts +10 -0
- package/dist/webauthn/decode-attestation-object.d.mts.map +1 -0
- package/dist/webauthn/decode-attestation-object.mjs +14 -0
- package/dist/webauthn/decode-attestation-object.mjs.map +1 -0
- package/dist/webauthn/decode-client-data-json.cjs +17 -0
- package/dist/webauthn/decode-client-data-json.cjs.map +1 -0
- package/dist/webauthn/decode-client-data-json.d.cts +9 -0
- package/dist/webauthn/decode-client-data-json.d.cts.map +1 -0
- package/dist/webauthn/decode-client-data-json.d.mts +9 -0
- package/dist/webauthn/decode-client-data-json.d.mts.map +1 -0
- package/dist/webauthn/decode-client-data-json.mjs +13 -0
- package/dist/webauthn/decode-client-data-json.mjs.map +1 -0
- package/dist/webauthn/match-expected-rp-id.cjs +43 -0
- package/dist/webauthn/match-expected-rp-id.cjs.map +1 -0
- package/dist/webauthn/match-expected-rp-id.d.cts +11 -0
- package/dist/webauthn/match-expected-rp-id.d.cts.map +1 -0
- package/dist/webauthn/match-expected-rp-id.d.mts +11 -0
- package/dist/webauthn/match-expected-rp-id.d.mts.map +1 -0
- package/dist/webauthn/match-expected-rp-id.mjs +39 -0
- package/dist/webauthn/match-expected-rp-id.mjs.map +1 -0
- package/dist/webauthn/parse-authenticator-data.cjs +69 -0
- package/dist/webauthn/parse-authenticator-data.cjs.map +1 -0
- package/dist/webauthn/parse-authenticator-data.d.cts +10 -0
- package/dist/webauthn/parse-authenticator-data.d.cts.map +1 -0
- package/dist/webauthn/parse-authenticator-data.d.mts +10 -0
- package/dist/webauthn/parse-authenticator-data.d.mts.map +1 -0
- package/dist/webauthn/parse-authenticator-data.mjs +65 -0
- package/dist/webauthn/parse-authenticator-data.mjs.map +1 -0
- package/dist/webauthn/types.cjs +3 -0
- package/dist/webauthn/types.cjs.map +1 -0
- package/dist/webauthn/types.d.cts +113 -0
- package/dist/webauthn/types.d.cts.map +1 -0
- package/dist/webauthn/types.d.mts +113 -0
- package/dist/webauthn/types.d.mts.map +1 -0
- package/dist/webauthn/types.mjs +2 -0
- package/dist/webauthn/types.mjs.map +1 -0
- package/dist/webauthn/verify-authentication-response.cjs +134 -0
- package/dist/webauthn/verify-authentication-response.cjs.map +1 -0
- package/dist/webauthn/verify-authentication-response.d.cts +63 -0
- package/dist/webauthn/verify-authentication-response.d.cts.map +1 -0
- package/dist/webauthn/verify-authentication-response.d.mts +63 -0
- package/dist/webauthn/verify-authentication-response.d.mts.map +1 -0
- package/dist/webauthn/verify-authentication-response.mjs +130 -0
- package/dist/webauthn/verify-authentication-response.mjs.map +1 -0
- package/dist/webauthn/verify-registration-response.cjs +205 -0
- package/dist/webauthn/verify-registration-response.cjs.map +1 -0
- package/dist/webauthn/verify-registration-response.d.cts +60 -0
- package/dist/webauthn/verify-registration-response.d.cts.map +1 -0
- package/dist/webauthn/verify-registration-response.d.mts +60 -0
- package/dist/webauthn/verify-registration-response.d.mts.map +1 -0
- package/dist/webauthn/verify-registration-response.mjs +201 -0
- package/dist/webauthn/verify-registration-response.mjs.map +1 -0
- package/dist/webauthn/verify-signature.cjs +176 -0
- package/dist/webauthn/verify-signature.cjs.map +1 -0
- package/dist/webauthn/verify-signature.d.cts +21 -0
- package/dist/webauthn/verify-signature.d.cts.map +1 -0
- package/dist/webauthn/verify-signature.d.mts +21 -0
- package/dist/webauthn/verify-signature.d.mts.map +1 -0
- package/dist/webauthn/verify-signature.mjs +172 -0
- package/dist/webauthn/verify-signature.mjs.map +1 -0
- package/package.json +78 -0
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export type Base64String = string;
|
|
2
|
+
export type Base64URLString = string;
|
|
3
|
+
export type AuthenticatorTransportFuture = 'ble' | 'cable' | 'hybrid' | 'internal' | 'nfc' | 'smart-card' | 'usb';
|
|
4
|
+
/**
|
|
5
|
+
* WebAuthn credential metadata used to identify the passkey and verify
|
|
6
|
+
* subsequent assertions.
|
|
7
|
+
*/
|
|
8
|
+
export type PasskeyCredentialInfo = {
|
|
9
|
+
/** WebAuthn credential ID (base64url). */
|
|
10
|
+
id: Base64URLString;
|
|
11
|
+
/** COSE-encoded credential public key (base64url) used to verify assertions. */
|
|
12
|
+
publicKey: Base64URLString;
|
|
13
|
+
/** Authenticator signature counter for replay/clone detection. */
|
|
14
|
+
counter: number;
|
|
15
|
+
/** Authenticator transports hint for `allowCredentials`. */
|
|
16
|
+
transports?: AuthenticatorTransportFuture[];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Vault key wrapped under the passkey-derived AES-256-GCM key.
|
|
20
|
+
*/
|
|
21
|
+
export type EncryptedVaultKey = {
|
|
22
|
+
/** Base64-encoded AES-256-GCM ciphertext of the vault key. */
|
|
23
|
+
ciphertext: Base64String;
|
|
24
|
+
/** Base64-encoded AES-GCM IV used during encryption. */
|
|
25
|
+
iv: Base64String;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Parameters needed to reproduce the AES-256 wrapping key at unlock time.
|
|
29
|
+
*
|
|
30
|
+
* Encoded as a discriminated union so PRF-only fields (e.g. `prfSalt`) can
|
|
31
|
+
* only exist on the PRF branch, removing the "optional but actually
|
|
32
|
+
* required" footgun.
|
|
33
|
+
*/
|
|
34
|
+
export type PasskeyKeyDerivation = {
|
|
35
|
+
method: 'prf';
|
|
36
|
+
/**
|
|
37
|
+
* PRF salt sent in `get()` extension options to reproduce the same PRF
|
|
38
|
+
* output that was generated at registration.
|
|
39
|
+
*/
|
|
40
|
+
prfSalt: Base64URLString;
|
|
41
|
+
} | {
|
|
42
|
+
method: 'userHandle';
|
|
43
|
+
};
|
|
44
|
+
/** Discriminator value for {@link PasskeyKeyDerivation}. */
|
|
45
|
+
export type PasskeyDerivationMethod = PasskeyKeyDerivation['method'];
|
|
46
|
+
export type PasskeyRecord = {
|
|
47
|
+
/** WebAuthn credential metadata used for assertion verification & re-discovery. */
|
|
48
|
+
credential: PasskeyCredentialInfo;
|
|
49
|
+
/** Vault key wrapped under the passkey-derived key. */
|
|
50
|
+
encryptedVaultKey: EncryptedVaultKey;
|
|
51
|
+
/** How the wrapping key is reconstructed at unlock time. */
|
|
52
|
+
keyDerivation: PasskeyKeyDerivation;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* In-memory state for one **in-flight** WebAuthn **registration** ceremony
|
|
56
|
+
* (from `create()` options until `protectVaultKeyWithPasskey` completes). This is
|
|
57
|
+
* not a user login session; it is keyed by challenge and distinct from the full
|
|
58
|
+
* spec ceremony (which includes the authenticator round-trip).
|
|
59
|
+
*/
|
|
60
|
+
export type PasskeyRegistrationCeremony = {
|
|
61
|
+
userHandle: Base64URLString;
|
|
62
|
+
prfSalt: Base64URLString;
|
|
63
|
+
challenge: Base64URLString;
|
|
64
|
+
/** When this ceremony was started (ms since epoch); used for TTL pruning. */
|
|
65
|
+
createdAt: number;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* In-memory state for one **in-flight** WebAuthn **authentication** ceremony
|
|
69
|
+
* (`get()` options until the assertion is verified). Not a user login session.
|
|
70
|
+
*/
|
|
71
|
+
export type PasskeyAuthenticationCeremony = {
|
|
72
|
+
challenge: Base64URLString;
|
|
73
|
+
/** When this ceremony was started (ms since epoch); used for TTL pruning. */
|
|
74
|
+
createdAt: number;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* PRF extension types not covered by DOM typings.
|
|
78
|
+
*/
|
|
79
|
+
export type PrfEvalExtension = {
|
|
80
|
+
eval: {
|
|
81
|
+
first: Base64URLString;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
export type PrfClientExtensionResults = {
|
|
85
|
+
prf?: {
|
|
86
|
+
enabled?: boolean;
|
|
87
|
+
results?: {
|
|
88
|
+
first?: Base64URLString;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAErC,MAAM,MAAM,4BAA4B,GACpC,KAAK,GACL,OAAO,GACP,QAAQ,GACR,UAAU,GACV,KAAK,GACL,YAAY,GACZ,KAAK,CAAC;AAEV;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,0CAA0C;IAC1C,EAAE,EAAE,eAAe,CAAC;IACpB,gFAAgF;IAChF,SAAS,EAAE,eAAe,CAAC;IAC3B,kEAAkE;IAClE,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,4BAA4B,EAAE,CAAC;CAC7C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,8DAA8D;IAC9D,UAAU,EAAE,YAAY,CAAC;IACzB,wDAAwD;IACxD,EAAE,EAAE,YAAY,CAAC;CAClB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE,MAAM,EAAE,KAAK,CAAC;IACd;;;OAGG;IACH,OAAO,EAAE,eAAe,CAAC;CAC1B,GACD;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,CAAC;AAE7B,4DAA4D;AAC5D,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAErE,MAAM,MAAM,aAAa,GAAG;IAC1B,mFAAmF;IACnF,UAAU,EAAE,qBAAqB,CAAC;IAClC,uDAAuD;IACvD,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,4DAA4D;IAC5D,aAAa,EAAE,oBAAoB,CAAC;CACrC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,eAAe,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,SAAS,EAAE,eAAe,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,eAAe,CAAC;KACxB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,CAAC,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,eAAe,CAAA;SAAE,CAAC;KACvC,CAAC;CACH,CAAC"}
|
package/dist/types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type Base64String = string;\n\nexport type Base64URLString = string;\n\nexport type AuthenticatorTransportFuture =\n | 'ble'\n | 'cable'\n | 'hybrid'\n | 'internal'\n | 'nfc'\n | 'smart-card'\n | 'usb';\n\n/**\n * WebAuthn credential metadata used to identify the passkey and verify\n * subsequent assertions.\n */\nexport type PasskeyCredentialInfo = {\n /** WebAuthn credential ID (base64url). */\n id: Base64URLString;\n /** COSE-encoded credential public key (base64url) used to verify assertions. */\n publicKey: Base64URLString;\n /** Authenticator signature counter for replay/clone detection. */\n counter: number;\n /** Authenticator transports hint for `allowCredentials`. */\n transports?: AuthenticatorTransportFuture[];\n};\n\n/**\n * Vault key wrapped under the passkey-derived AES-256-GCM key.\n */\nexport type EncryptedVaultKey = {\n /** Base64-encoded AES-256-GCM ciphertext of the vault key. */\n ciphertext: Base64String;\n /** Base64-encoded AES-GCM IV used during encryption. */\n iv: Base64String;\n};\n\n/**\n * Parameters needed to reproduce the AES-256 wrapping key at unlock time.\n *\n * Encoded as a discriminated union so PRF-only fields (e.g. `prfSalt`) can\n * only exist on the PRF branch, removing the \"optional but actually\n * required\" footgun.\n */\nexport type PasskeyKeyDerivation =\n | {\n method: 'prf';\n /**\n * PRF salt sent in `get()` extension options to reproduce the same PRF\n * output that was generated at registration.\n */\n prfSalt: Base64URLString;\n }\n | { method: 'userHandle' };\n\n/** Discriminator value for {@link PasskeyKeyDerivation}. */\nexport type PasskeyDerivationMethod = PasskeyKeyDerivation['method'];\n\nexport type PasskeyRecord = {\n /** WebAuthn credential metadata used for assertion verification & re-discovery. */\n credential: PasskeyCredentialInfo;\n /** Vault key wrapped under the passkey-derived key. */\n encryptedVaultKey: EncryptedVaultKey;\n /** How the wrapping key is reconstructed at unlock time. */\n keyDerivation: PasskeyKeyDerivation;\n};\n\n/**\n * In-memory state for one **in-flight** WebAuthn **registration** ceremony\n * (from `create()` options until `protectVaultKeyWithPasskey` completes). This is\n * not a user login session; it is keyed by challenge and distinct from the full\n * spec ceremony (which includes the authenticator round-trip).\n */\nexport type PasskeyRegistrationCeremony = {\n userHandle: Base64URLString;\n prfSalt: Base64URLString;\n challenge: Base64URLString;\n /** When this ceremony was started (ms since epoch); used for TTL pruning. */\n createdAt: number;\n};\n\n/**\n * In-memory state for one **in-flight** WebAuthn **authentication** ceremony\n * (`get()` options until the assertion is verified). Not a user login session.\n */\nexport type PasskeyAuthenticationCeremony = {\n challenge: Base64URLString;\n /** When this ceremony was started (ms since epoch); used for TTL pruning. */\n createdAt: number;\n};\n\n/**\n * PRF extension types not covered by DOM typings.\n */\nexport type PrfEvalExtension = {\n eval: {\n first: Base64URLString;\n };\n};\n\nexport type PrfClientExtensionResults = {\n prf?: {\n enabled?: boolean;\n results?: { first?: Base64URLString };\n };\n};\n"]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.decryptWithKey = exports.encryptWithKey = exports.deriveEncryptionKey = void 0;
|
|
4
|
+
const utils_1 = require("@metamask/utils");
|
|
5
|
+
const aes_1 = require("@noble/ciphers/aes");
|
|
6
|
+
const webcrypto_1 = require("@noble/ciphers/webcrypto");
|
|
7
|
+
const hkdf_1 = require("@noble/hashes/hkdf");
|
|
8
|
+
const sha2_1 = require("@noble/hashes/sha2");
|
|
9
|
+
const PASSKEY_HKDF_INFO = 'metamask:passkey:encryption-key:v1';
|
|
10
|
+
const AES_GCM_IV_LENGTH = 12;
|
|
11
|
+
/**
|
|
12
|
+
* Derives an AES-256 encryption key from input key material and a credential ID
|
|
13
|
+
* using HKDF-SHA256.
|
|
14
|
+
*
|
|
15
|
+
* @param ikm - Input key material (e.g. PRF output or userHandle).
|
|
16
|
+
* @param salt - HKDF salt.
|
|
17
|
+
* @returns 32-byte derived encryption key.
|
|
18
|
+
*/
|
|
19
|
+
function deriveEncryptionKey(ikm, salt) {
|
|
20
|
+
return (0, hkdf_1.hkdf)(sha2_1.sha256, ikm, salt, PASSKEY_HKDF_INFO, 32);
|
|
21
|
+
}
|
|
22
|
+
exports.deriveEncryptionKey = deriveEncryptionKey;
|
|
23
|
+
/**
|
|
24
|
+
* Encrypts plaintext with an AES-256-GCM key.
|
|
25
|
+
*
|
|
26
|
+
* @param plaintext - UTF-8 string to encrypt.
|
|
27
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
28
|
+
* @returns Base64-encoded ciphertext and IV.
|
|
29
|
+
*/
|
|
30
|
+
function encryptWithKey(plaintext, key) {
|
|
31
|
+
const iv = (0, webcrypto_1.randomBytes)(AES_GCM_IV_LENGTH);
|
|
32
|
+
const encoded = new TextEncoder().encode(plaintext);
|
|
33
|
+
const ciphertextBytes = (0, aes_1.gcm)(key, iv).encrypt(encoded);
|
|
34
|
+
return {
|
|
35
|
+
ciphertext: (0, utils_1.bytesToBase64)(ciphertextBytes),
|
|
36
|
+
iv: (0, utils_1.bytesToBase64)(iv),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
exports.encryptWithKey = encryptWithKey;
|
|
40
|
+
/**
|
|
41
|
+
* Decrypts AES-256-GCM ciphertext with the given key.
|
|
42
|
+
*
|
|
43
|
+
* @param ciphertext - Base64-encoded ciphertext.
|
|
44
|
+
* @param iv - Base64-encoded initialization vector.
|
|
45
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
46
|
+
* @returns Decrypted UTF-8 string.
|
|
47
|
+
*/
|
|
48
|
+
function decryptWithKey(ciphertext, iv, key) {
|
|
49
|
+
const ciphertextBytes = (0, utils_1.base64ToBytes)(ciphertext);
|
|
50
|
+
const ivBytes = (0, utils_1.base64ToBytes)(iv);
|
|
51
|
+
const plaintext = (0, aes_1.gcm)(key, ivBytes).decrypt(ciphertextBytes);
|
|
52
|
+
return new TextDecoder().decode(plaintext);
|
|
53
|
+
}
|
|
54
|
+
exports.decryptWithKey = decryptWithKey;
|
|
55
|
+
//# sourceMappingURL=crypto.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.cjs","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":";;;AAAA,2CAA+D;AAC/D,4CAAyC;AACzC,wDAAuD;AACvD,6CAA0C;AAC1C,6CAA4C;AAE5C,MAAM,iBAAiB,GAAG,oCAAoC,CAAC;AAE/D,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,GAAe,EACf,IAAgB;IAEhB,OAAO,IAAA,WAAI,EAAC,aAAM,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;AACxD,CAAC;AALD,kDAKC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAC5B,SAAiB,EACjB,GAAe;IAEf,MAAM,EAAE,GAAG,IAAA,uBAAW,EAAC,iBAAiB,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,eAAe,GAAG,IAAA,SAAG,EAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtD,OAAO;QACL,UAAU,EAAE,IAAA,qBAAa,EAAC,eAAe,CAAC;QAC1C,EAAE,EAAE,IAAA,qBAAa,EAAC,EAAE,CAAC;KACtB,CAAC;AACJ,CAAC;AAZD,wCAYC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC5B,UAAkB,EAClB,EAAU,EACV,GAAe;IAEf,MAAM,eAAe,GAAG,IAAA,qBAAa,EAAC,UAAU,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,EAAE,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,IAAA,SAAG,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7D,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC;AAVD,wCAUC","sourcesContent":["import { bytesToBase64, base64ToBytes } from '@metamask/utils';\nimport { gcm } from '@noble/ciphers/aes';\nimport { randomBytes } from '@noble/ciphers/webcrypto';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport { sha256 } from '@noble/hashes/sha2';\n\nconst PASSKEY_HKDF_INFO = 'metamask:passkey:encryption-key:v1';\n\nconst AES_GCM_IV_LENGTH = 12;\n\n/**\n * Derives an AES-256 encryption key from input key material and a credential ID\n * using HKDF-SHA256.\n *\n * @param ikm - Input key material (e.g. PRF output or userHandle).\n * @param salt - HKDF salt.\n * @returns 32-byte derived encryption key.\n */\nexport function deriveEncryptionKey(\n ikm: Uint8Array,\n salt: Uint8Array,\n): Uint8Array {\n return hkdf(sha256, ikm, salt, PASSKEY_HKDF_INFO, 32);\n}\n\n/**\n * Encrypts plaintext with an AES-256-GCM key.\n *\n * @param plaintext - UTF-8 string to encrypt.\n * @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.\n * @returns Base64-encoded ciphertext and IV.\n */\nexport function encryptWithKey(\n plaintext: string,\n key: Uint8Array,\n): { ciphertext: string; iv: string } {\n const iv = randomBytes(AES_GCM_IV_LENGTH);\n const encoded = new TextEncoder().encode(plaintext);\n const ciphertextBytes = gcm(key, iv).encrypt(encoded);\n\n return {\n ciphertext: bytesToBase64(ciphertextBytes),\n iv: bytesToBase64(iv),\n };\n}\n\n/**\n * Decrypts AES-256-GCM ciphertext with the given key.\n *\n * @param ciphertext - Base64-encoded ciphertext.\n * @param iv - Base64-encoded initialization vector.\n * @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.\n * @returns Decrypted UTF-8 string.\n */\nexport function decryptWithKey(\n ciphertext: string,\n iv: string,\n key: Uint8Array,\n): string {\n const ciphertextBytes = base64ToBytes(ciphertext);\n const ivBytes = base64ToBytes(iv);\n const plaintext = gcm(key, ivBytes).decrypt(ciphertextBytes);\n\n return new TextDecoder().decode(plaintext);\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives an AES-256 encryption key from input key material and a credential ID
|
|
3
|
+
* using HKDF-SHA256.
|
|
4
|
+
*
|
|
5
|
+
* @param ikm - Input key material (e.g. PRF output or userHandle).
|
|
6
|
+
* @param salt - HKDF salt.
|
|
7
|
+
* @returns 32-byte derived encryption key.
|
|
8
|
+
*/
|
|
9
|
+
export declare function deriveEncryptionKey(ikm: Uint8Array, salt: Uint8Array): Uint8Array;
|
|
10
|
+
/**
|
|
11
|
+
* Encrypts plaintext with an AES-256-GCM key.
|
|
12
|
+
*
|
|
13
|
+
* @param plaintext - UTF-8 string to encrypt.
|
|
14
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
15
|
+
* @returns Base64-encoded ciphertext and IV.
|
|
16
|
+
*/
|
|
17
|
+
export declare function encryptWithKey(plaintext: string, key: Uint8Array): {
|
|
18
|
+
ciphertext: string;
|
|
19
|
+
iv: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Decrypts AES-256-GCM ciphertext with the given key.
|
|
23
|
+
*
|
|
24
|
+
* @param ciphertext - Base64-encoded ciphertext.
|
|
25
|
+
* @param iv - Base64-encoded initialization vector.
|
|
26
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
27
|
+
* @returns Decrypted UTF-8 string.
|
|
28
|
+
*/
|
|
29
|
+
export declare function decryptWithKey(ciphertext: string, iv: string, key: Uint8Array): string;
|
|
30
|
+
//# sourceMappingURL=crypto.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.cts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,UAAU,GACf,UAAU,CAEZ;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,GACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CASpC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,UAAU,GACd,MAAM,CAMR"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derives an AES-256 encryption key from input key material and a credential ID
|
|
3
|
+
* using HKDF-SHA256.
|
|
4
|
+
*
|
|
5
|
+
* @param ikm - Input key material (e.g. PRF output or userHandle).
|
|
6
|
+
* @param salt - HKDF salt.
|
|
7
|
+
* @returns 32-byte derived encryption key.
|
|
8
|
+
*/
|
|
9
|
+
export declare function deriveEncryptionKey(ikm: Uint8Array, salt: Uint8Array): Uint8Array;
|
|
10
|
+
/**
|
|
11
|
+
* Encrypts plaintext with an AES-256-GCM key.
|
|
12
|
+
*
|
|
13
|
+
* @param plaintext - UTF-8 string to encrypt.
|
|
14
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
15
|
+
* @returns Base64-encoded ciphertext and IV.
|
|
16
|
+
*/
|
|
17
|
+
export declare function encryptWithKey(plaintext: string, key: Uint8Array): {
|
|
18
|
+
ciphertext: string;
|
|
19
|
+
iv: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Decrypts AES-256-GCM ciphertext with the given key.
|
|
23
|
+
*
|
|
24
|
+
* @param ciphertext - Base64-encoded ciphertext.
|
|
25
|
+
* @param iv - Base64-encoded initialization vector.
|
|
26
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
27
|
+
* @returns Decrypted UTF-8 string.
|
|
28
|
+
*/
|
|
29
|
+
export declare function decryptWithKey(ciphertext: string, iv: string, key: Uint8Array): string;
|
|
30
|
+
//# sourceMappingURL=crypto.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.mts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAUA;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,UAAU,GACf,UAAU,CAEZ;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,UAAU,GACd;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CASpC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,UAAU,GACd,MAAM,CAMR"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { bytesToBase64, base64ToBytes } from "@metamask/utils";
|
|
2
|
+
import { gcm } from "@noble/ciphers/aes";
|
|
3
|
+
import { randomBytes } from "@noble/ciphers/webcrypto";
|
|
4
|
+
import { hkdf } from "@noble/hashes/hkdf";
|
|
5
|
+
import { sha256 } from "@noble/hashes/sha2";
|
|
6
|
+
const PASSKEY_HKDF_INFO = 'metamask:passkey:encryption-key:v1';
|
|
7
|
+
const AES_GCM_IV_LENGTH = 12;
|
|
8
|
+
/**
|
|
9
|
+
* Derives an AES-256 encryption key from input key material and a credential ID
|
|
10
|
+
* using HKDF-SHA256.
|
|
11
|
+
*
|
|
12
|
+
* @param ikm - Input key material (e.g. PRF output or userHandle).
|
|
13
|
+
* @param salt - HKDF salt.
|
|
14
|
+
* @returns 32-byte derived encryption key.
|
|
15
|
+
*/
|
|
16
|
+
export function deriveEncryptionKey(ikm, salt) {
|
|
17
|
+
return hkdf(sha256, ikm, salt, PASSKEY_HKDF_INFO, 32);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Encrypts plaintext with an AES-256-GCM key.
|
|
21
|
+
*
|
|
22
|
+
* @param plaintext - UTF-8 string to encrypt.
|
|
23
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
24
|
+
* @returns Base64-encoded ciphertext and IV.
|
|
25
|
+
*/
|
|
26
|
+
export function encryptWithKey(plaintext, key) {
|
|
27
|
+
const iv = randomBytes(AES_GCM_IV_LENGTH);
|
|
28
|
+
const encoded = new TextEncoder().encode(plaintext);
|
|
29
|
+
const ciphertextBytes = gcm(key, iv).encrypt(encoded);
|
|
30
|
+
return {
|
|
31
|
+
ciphertext: bytesToBase64(ciphertextBytes),
|
|
32
|
+
iv: bytesToBase64(iv),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Decrypts AES-256-GCM ciphertext with the given key.
|
|
37
|
+
*
|
|
38
|
+
* @param ciphertext - Base64-encoded ciphertext.
|
|
39
|
+
* @param iv - Base64-encoded initialization vector.
|
|
40
|
+
* @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.
|
|
41
|
+
* @returns Decrypted UTF-8 string.
|
|
42
|
+
*/
|
|
43
|
+
export function decryptWithKey(ciphertext, iv, key) {
|
|
44
|
+
const ciphertextBytes = base64ToBytes(ciphertext);
|
|
45
|
+
const ivBytes = base64ToBytes(iv);
|
|
46
|
+
const plaintext = gcm(key, ivBytes).decrypt(ciphertextBytes);
|
|
47
|
+
return new TextDecoder().decode(plaintext);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=crypto.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.mjs","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB;AAC/D,OAAO,EAAE,GAAG,EAAE,2BAA2B;AACzC,OAAO,EAAE,WAAW,EAAE,iCAAiC;AACvD,OAAO,EAAE,IAAI,EAAE,2BAA2B;AAC1C,OAAO,EAAE,MAAM,EAAE,2BAA2B;AAE5C,MAAM,iBAAiB,GAAG,oCAAoC,CAAC;AAE/D,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAe,EACf,IAAgB;IAEhB,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAiB,EACjB,GAAe;IAEf,MAAM,EAAE,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,eAAe,GAAG,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtD,OAAO;QACL,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC;QAC1C,EAAE,EAAE,aAAa,CAAC,EAAE,CAAC;KACtB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,UAAkB,EAClB,EAAU,EACV,GAAe;IAEf,MAAM,eAAe,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;IAClC,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7D,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["import { bytesToBase64, base64ToBytes } from '@metamask/utils';\nimport { gcm } from '@noble/ciphers/aes';\nimport { randomBytes } from '@noble/ciphers/webcrypto';\nimport { hkdf } from '@noble/hashes/hkdf';\nimport { sha256 } from '@noble/hashes/sha2';\n\nconst PASSKEY_HKDF_INFO = 'metamask:passkey:encryption-key:v1';\n\nconst AES_GCM_IV_LENGTH = 12;\n\n/**\n * Derives an AES-256 encryption key from input key material and a credential ID\n * using HKDF-SHA256.\n *\n * @param ikm - Input key material (e.g. PRF output or userHandle).\n * @param salt - HKDF salt.\n * @returns 32-byte derived encryption key.\n */\nexport function deriveEncryptionKey(\n ikm: Uint8Array,\n salt: Uint8Array,\n): Uint8Array {\n return hkdf(sha256, ikm, salt, PASSKEY_HKDF_INFO, 32);\n}\n\n/**\n * Encrypts plaintext with an AES-256-GCM key.\n *\n * @param plaintext - UTF-8 string to encrypt.\n * @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.\n * @returns Base64-encoded ciphertext and IV.\n */\nexport function encryptWithKey(\n plaintext: string,\n key: Uint8Array,\n): { ciphertext: string; iv: string } {\n const iv = randomBytes(AES_GCM_IV_LENGTH);\n const encoded = new TextEncoder().encode(plaintext);\n const ciphertextBytes = gcm(key, iv).encrypt(encoded);\n\n return {\n ciphertext: bytesToBase64(ciphertextBytes),\n iv: bytesToBase64(iv),\n };\n}\n\n/**\n * Decrypts AES-256-GCM ciphertext with the given key.\n *\n * @param ciphertext - Base64-encoded ciphertext.\n * @param iv - Base64-encoded initialization vector.\n * @param key - 32-byte AES-256 key from {@link deriveEncryptionKey}.\n * @returns Decrypted UTF-8 string.\n */\nexport function decryptWithKey(\n ciphertext: string,\n iv: string,\n key: Uint8Array,\n): string {\n const ciphertextBytes = base64ToBytes(ciphertext);\n const ivBytes = base64ToBytes(iv);\n const plaintext = gcm(key, ivBytes).decrypt(ciphertextBytes);\n\n return new TextDecoder().decode(plaintext);\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bytesToHex = exports.base64URLToBytes = exports.bytesToBase64URL = void 0;
|
|
4
|
+
const utils_1 = require("@metamask/utils");
|
|
5
|
+
/**
|
|
6
|
+
* Encode a byte array as a base64url string (RFC 4648 §5).
|
|
7
|
+
*
|
|
8
|
+
* @param bytes - The bytes to encode.
|
|
9
|
+
* @returns Base64url-encoded string without padding.
|
|
10
|
+
*/
|
|
11
|
+
function bytesToBase64URL(bytes) {
|
|
12
|
+
return (0, utils_1.bytesToBase64)(bytes)
|
|
13
|
+
.replace(/\+/gu, '-')
|
|
14
|
+
.replace(/\//gu, '_')
|
|
15
|
+
.replace(/[=]+$/u, '');
|
|
16
|
+
}
|
|
17
|
+
exports.bytesToBase64URL = bytesToBase64URL;
|
|
18
|
+
/**
|
|
19
|
+
* Decode a base64url string (RFC 4648 §5) into bytes.
|
|
20
|
+
*
|
|
21
|
+
* @param value - Base64url-encoded string.
|
|
22
|
+
* @returns Decoded bytes.
|
|
23
|
+
*/
|
|
24
|
+
function base64URLToBytes(value) {
|
|
25
|
+
const standard = value.replace(/-/gu, '+').replace(/_/gu, '/');
|
|
26
|
+
const padLength = (4 - (standard.length % 4)) % 4;
|
|
27
|
+
return Uint8Array.from((0, utils_1.base64ToBytes)(standard + '='.repeat(padLength)));
|
|
28
|
+
}
|
|
29
|
+
exports.base64URLToBytes = base64URLToBytes;
|
|
30
|
+
/**
|
|
31
|
+
* Encode a byte array as a hexadecimal string.
|
|
32
|
+
*
|
|
33
|
+
* @param bytes - The bytes to encode.
|
|
34
|
+
* @returns Hex-encoded string.
|
|
35
|
+
*/
|
|
36
|
+
function bytesToHex(bytes) {
|
|
37
|
+
return Array.from(bytes)
|
|
38
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
39
|
+
.join('');
|
|
40
|
+
}
|
|
41
|
+
exports.bytesToHex = bytesToHex;
|
|
42
|
+
//# sourceMappingURL=encoding.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.cjs","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":";;;AAAA,2CAA+D;AAE/D;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,KAAiB;IAChD,OAAO,IAAA,qBAAa,EAAC,KAAK,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AALD,4CAKC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,UAAU,CAAC,IAAI,CAAC,IAAA,qBAAa,EAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAJD,4CAIC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,KAAiB;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SACjD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAJD,gCAIC","sourcesContent":["import { bytesToBase64, base64ToBytes } from '@metamask/utils';\n\n/**\n * Encode a byte array as a base64url string (RFC 4648 §5).\n *\n * @param bytes - The bytes to encode.\n * @returns Base64url-encoded string without padding.\n */\nexport function bytesToBase64URL(bytes: Uint8Array): string {\n return bytesToBase64(bytes)\n .replace(/\\+/gu, '-')\n .replace(/\\//gu, '_')\n .replace(/[=]+$/u, '');\n}\n\n/**\n * Decode a base64url string (RFC 4648 §5) into bytes.\n *\n * @param value - Base64url-encoded string.\n * @returns Decoded bytes.\n */\nexport function base64URLToBytes(value: string): Uint8Array {\n const standard = value.replace(/-/gu, '+').replace(/_/gu, '/');\n const padLength = (4 - (standard.length % 4)) % 4;\n return Uint8Array.from(base64ToBytes(standard + '='.repeat(padLength)));\n}\n\n/**\n * Encode a byte array as a hexadecimal string.\n *\n * @param bytes - The bytes to encode.\n * @returns Hex-encoded string.\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('');\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode a byte array as a base64url string (RFC 4648 §5).
|
|
3
|
+
*
|
|
4
|
+
* @param bytes - The bytes to encode.
|
|
5
|
+
* @returns Base64url-encoded string without padding.
|
|
6
|
+
*/
|
|
7
|
+
export declare function bytesToBase64URL(bytes: Uint8Array): string;
|
|
8
|
+
/**
|
|
9
|
+
* Decode a base64url string (RFC 4648 §5) into bytes.
|
|
10
|
+
*
|
|
11
|
+
* @param value - Base64url-encoded string.
|
|
12
|
+
* @returns Decoded bytes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function base64URLToBytes(value: string): Uint8Array;
|
|
15
|
+
/**
|
|
16
|
+
* Encode a byte array as a hexadecimal string.
|
|
17
|
+
*
|
|
18
|
+
* @param bytes - The bytes to encode.
|
|
19
|
+
* @returns Hex-encoded string.
|
|
20
|
+
*/
|
|
21
|
+
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
22
|
+
//# sourceMappingURL=encoding.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.d.cts","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAK1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAI1D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode a byte array as a base64url string (RFC 4648 §5).
|
|
3
|
+
*
|
|
4
|
+
* @param bytes - The bytes to encode.
|
|
5
|
+
* @returns Base64url-encoded string without padding.
|
|
6
|
+
*/
|
|
7
|
+
export declare function bytesToBase64URL(bytes: Uint8Array): string;
|
|
8
|
+
/**
|
|
9
|
+
* Decode a base64url string (RFC 4648 §5) into bytes.
|
|
10
|
+
*
|
|
11
|
+
* @param value - Base64url-encoded string.
|
|
12
|
+
* @returns Decoded bytes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function base64URLToBytes(value: string): Uint8Array;
|
|
15
|
+
/**
|
|
16
|
+
* Encode a byte array as a hexadecimal string.
|
|
17
|
+
*
|
|
18
|
+
* @param bytes - The bytes to encode.
|
|
19
|
+
* @returns Hex-encoded string.
|
|
20
|
+
*/
|
|
21
|
+
export declare function bytesToHex(bytes: Uint8Array): string;
|
|
22
|
+
//# sourceMappingURL=encoding.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.d.mts","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAK1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAI1D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIpD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { bytesToBase64, base64ToBytes } from "@metamask/utils";
|
|
2
|
+
/**
|
|
3
|
+
* Encode a byte array as a base64url string (RFC 4648 §5).
|
|
4
|
+
*
|
|
5
|
+
* @param bytes - The bytes to encode.
|
|
6
|
+
* @returns Base64url-encoded string without padding.
|
|
7
|
+
*/
|
|
8
|
+
export function bytesToBase64URL(bytes) {
|
|
9
|
+
return bytesToBase64(bytes)
|
|
10
|
+
.replace(/\+/gu, '-')
|
|
11
|
+
.replace(/\//gu, '_')
|
|
12
|
+
.replace(/[=]+$/u, '');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Decode a base64url string (RFC 4648 §5) into bytes.
|
|
16
|
+
*
|
|
17
|
+
* @param value - Base64url-encoded string.
|
|
18
|
+
* @returns Decoded bytes.
|
|
19
|
+
*/
|
|
20
|
+
export function base64URLToBytes(value) {
|
|
21
|
+
const standard = value.replace(/-/gu, '+').replace(/_/gu, '/');
|
|
22
|
+
const padLength = (4 - (standard.length % 4)) % 4;
|
|
23
|
+
return Uint8Array.from(base64ToBytes(standard + '='.repeat(padLength)));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Encode a byte array as a hexadecimal string.
|
|
27
|
+
*
|
|
28
|
+
* @param bytes - The bytes to encode.
|
|
29
|
+
* @returns Hex-encoded string.
|
|
30
|
+
*/
|
|
31
|
+
export function bytesToHex(bytes) {
|
|
32
|
+
return Array.from(bytes)
|
|
33
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
34
|
+
.join('');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=encoding.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encoding.mjs","sourceRoot":"","sources":["../../src/utils/encoding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB;AAE/D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,OAAO,aAAa,CAAC,KAAK,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB;IAC1C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SACjD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC","sourcesContent":["import { bytesToBase64, base64ToBytes } from '@metamask/utils';\n\n/**\n * Encode a byte array as a base64url string (RFC 4648 §5).\n *\n * @param bytes - The bytes to encode.\n * @returns Base64url-encoded string without padding.\n */\nexport function bytesToBase64URL(bytes: Uint8Array): string {\n return bytesToBase64(bytes)\n .replace(/\\+/gu, '-')\n .replace(/\\//gu, '_')\n .replace(/[=]+$/u, '');\n}\n\n/**\n * Decode a base64url string (RFC 4648 §5) into bytes.\n *\n * @param value - Base64url-encoded string.\n * @returns Decoded bytes.\n */\nexport function base64URLToBytes(value: string): Uint8Array {\n const standard = value.replace(/-/gu, '+').replace(/_/gu, '/');\n const padLength = (4 - (standard.length % 4)) % 4;\n return Uint8Array.from(base64ToBytes(standard + '='.repeat(padLength)));\n}\n\n/**\n * Encode a byte array as a hexadecimal string.\n *\n * @param bytes - The bytes to encode.\n * @returns Hex-encoded string.\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, '0'))\n .join('');\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COSEKEYS = exports.COSECRV = exports.COSEKTY = exports.COSEALG = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* COSE Algorithms
|
|
6
|
+
*
|
|
7
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#algorithms
|
|
8
|
+
*/
|
|
9
|
+
var COSEALG;
|
|
10
|
+
(function (COSEALG) {
|
|
11
|
+
COSEALG[COSEALG["ES256"] = -7] = "ES256";
|
|
12
|
+
COSEALG[COSEALG["EdDSA"] = -8] = "EdDSA";
|
|
13
|
+
COSEALG[COSEALG["ES384"] = -35] = "ES384";
|
|
14
|
+
COSEALG[COSEALG["ES512"] = -36] = "ES512";
|
|
15
|
+
COSEALG[COSEALG["PS256"] = -37] = "PS256";
|
|
16
|
+
COSEALG[COSEALG["PS384"] = -38] = "PS384";
|
|
17
|
+
COSEALG[COSEALG["PS512"] = -39] = "PS512";
|
|
18
|
+
COSEALG[COSEALG["ES256K"] = -47] = "ES256K";
|
|
19
|
+
COSEALG[COSEALG["RS256"] = -257] = "RS256";
|
|
20
|
+
COSEALG[COSEALG["RS384"] = -258] = "RS384";
|
|
21
|
+
COSEALG[COSEALG["RS512"] = -259] = "RS512";
|
|
22
|
+
COSEALG[COSEALG["RS1"] = -65535] = "RS1";
|
|
23
|
+
})(COSEALG || (exports.COSEALG = COSEALG = {}));
|
|
24
|
+
/**
|
|
25
|
+
* COSE Key Types
|
|
26
|
+
*
|
|
27
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-type
|
|
28
|
+
*/
|
|
29
|
+
var COSEKTY;
|
|
30
|
+
(function (COSEKTY) {
|
|
31
|
+
COSEKTY[COSEKTY["OKP"] = 1] = "OKP";
|
|
32
|
+
COSEKTY[COSEKTY["EC2"] = 2] = "EC2";
|
|
33
|
+
COSEKTY[COSEKTY["RSA"] = 3] = "RSA";
|
|
34
|
+
})(COSEKTY || (exports.COSEKTY = COSEKTY = {}));
|
|
35
|
+
/**
|
|
36
|
+
* COSE Curves
|
|
37
|
+
*
|
|
38
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
|
|
39
|
+
*/
|
|
40
|
+
var COSECRV;
|
|
41
|
+
(function (COSECRV) {
|
|
42
|
+
COSECRV[COSECRV["P256"] = 1] = "P256";
|
|
43
|
+
COSECRV[COSECRV["P384"] = 2] = "P384";
|
|
44
|
+
COSECRV[COSECRV["P521"] = 3] = "P521";
|
|
45
|
+
COSECRV[COSECRV["ED25519"] = 6] = "ED25519";
|
|
46
|
+
COSECRV[COSECRV["SECP256K1"] = 8] = "SECP256K1";
|
|
47
|
+
})(COSECRV || (exports.COSECRV = COSECRV = {}));
|
|
48
|
+
/**
|
|
49
|
+
* COSE Key common and type-specific parameter labels.
|
|
50
|
+
*
|
|
51
|
+
* EC2 and RSA re-use the same numeric labels (-1, -2, -3) with different
|
|
52
|
+
* semantics, so this is a plain object instead of an enum to avoid
|
|
53
|
+
* duplicate-value violations.
|
|
54
|
+
*
|
|
55
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters
|
|
56
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters
|
|
57
|
+
*/
|
|
58
|
+
exports.COSEKEYS = {
|
|
59
|
+
/** Key Type (common) */
|
|
60
|
+
Kty: 1,
|
|
61
|
+
/** Algorithm (common) */
|
|
62
|
+
Alg: 3,
|
|
63
|
+
/** EC2 / OKP: curve identifier */
|
|
64
|
+
Crv: -1,
|
|
65
|
+
/** EC2: x-coordinate / OKP: public key */
|
|
66
|
+
X: -2,
|
|
67
|
+
/** EC2: y-coordinate */
|
|
68
|
+
Y: -3,
|
|
69
|
+
/** RSA: modulus n (shares numeric label with Crv) */
|
|
70
|
+
N: -1,
|
|
71
|
+
/** RSA: exponent e (shares numeric label with X) */
|
|
72
|
+
E: -2,
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=constants.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.cjs","sourceRoot":"","sources":["../../src/webauthn/constants.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,IAAY,OAaX;AAbD,WAAY,OAAO;IACjB,wCAAU,CAAA;IACV,wCAAU,CAAA;IACV,yCAAW,CAAA;IACX,yCAAW,CAAA;IACX,yCAAW,CAAA;IACX,yCAAW,CAAA;IACX,yCAAW,CAAA;IACX,2CAAY,CAAA;IACZ,0CAAY,CAAA;IACZ,0CAAY,CAAA;IACZ,0CAAY,CAAA;IACZ,wCAAY,CAAA;AACd,CAAC,EAbW,OAAO,uBAAP,OAAO,QAalB;AAED;;;;GAIG;AACH,IAAY,OAIX;AAJD,WAAY,OAAO;IACjB,mCAAO,CAAA;IACP,mCAAO,CAAA;IACP,mCAAO,CAAA;AACT,CAAC,EAJW,OAAO,uBAAP,OAAO,QAIlB;AAED;;;;GAIG;AACH,IAAY,OAMX;AAND,WAAY,OAAO;IACjB,qCAAQ,CAAA;IACR,qCAAQ,CAAA;IACR,qCAAQ,CAAA;IACR,2CAAW,CAAA;IACX,+CAAa,CAAA;AACf,CAAC,EANW,OAAO,uBAAP,OAAO,QAMlB;AAED;;;;;;;;;GASG;AACU,QAAA,QAAQ,GAAG;IACtB,wBAAwB;IACxB,GAAG,EAAE,CAAC;IACN,yBAAyB;IACzB,GAAG,EAAE,CAAC;IAEN,kCAAkC;IAClC,GAAG,EAAE,CAAC,CAAC;IACP,0CAA0C;IAC1C,CAAC,EAAE,CAAC,CAAC;IACL,wBAAwB;IACxB,CAAC,EAAE,CAAC,CAAC;IAEL,qDAAqD;IACrD,CAAC,EAAE,CAAC,CAAC;IACL,oDAAoD;IACpD,CAAC,EAAE,CAAC,CAAC;CACG,CAAC","sourcesContent":["/**\n * COSE Algorithms\n *\n * @see https://www.iana.org/assignments/cose/cose.xhtml#algorithms\n */\nexport enum COSEALG {\n ES256 = -7,\n EdDSA = -8,\n ES384 = -35,\n ES512 = -36,\n PS256 = -37,\n PS384 = -38,\n PS512 = -39,\n ES256K = -47,\n RS256 = -257,\n RS384 = -258,\n RS512 = -259,\n RS1 = -65535,\n}\n\n/**\n * COSE Key Types\n *\n * @see https://www.iana.org/assignments/cose/cose.xhtml#key-type\n */\nexport enum COSEKTY {\n OKP = 1,\n EC2 = 2,\n RSA = 3,\n}\n\n/**\n * COSE Curves\n *\n * @see https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves\n */\nexport enum COSECRV {\n P256 = 1,\n P384 = 2,\n P521 = 3,\n ED25519 = 6,\n SECP256K1 = 8,\n}\n\n/**\n * COSE Key common and type-specific parameter labels.\n *\n * EC2 and RSA re-use the same numeric labels (-1, -2, -3) with different\n * semantics, so this is a plain object instead of an enum to avoid\n * duplicate-value violations.\n *\n * @see https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters\n * @see https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters\n */\nexport const COSEKEYS = {\n /** Key Type (common) */\n Kty: 1,\n /** Algorithm (common) */\n Alg: 3,\n\n /** EC2 / OKP: curve identifier */\n Crv: -1,\n /** EC2: x-coordinate / OKP: public key */\n X: -2,\n /** EC2: y-coordinate */\n Y: -3,\n\n /** RSA: modulus n (shares numeric label with Crv) */\n N: -1,\n /** RSA: exponent e (shares numeric label with X) */\n E: -2,\n} as const;\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COSE Algorithms
|
|
3
|
+
*
|
|
4
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#algorithms
|
|
5
|
+
*/
|
|
6
|
+
export declare enum COSEALG {
|
|
7
|
+
ES256 = -7,
|
|
8
|
+
EdDSA = -8,
|
|
9
|
+
ES384 = -35,
|
|
10
|
+
ES512 = -36,
|
|
11
|
+
PS256 = -37,
|
|
12
|
+
PS384 = -38,
|
|
13
|
+
PS512 = -39,
|
|
14
|
+
ES256K = -47,
|
|
15
|
+
RS256 = -257,
|
|
16
|
+
RS384 = -258,
|
|
17
|
+
RS512 = -259,
|
|
18
|
+
RS1 = -65535
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* COSE Key Types
|
|
22
|
+
*
|
|
23
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-type
|
|
24
|
+
*/
|
|
25
|
+
export declare enum COSEKTY {
|
|
26
|
+
OKP = 1,
|
|
27
|
+
EC2 = 2,
|
|
28
|
+
RSA = 3
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* COSE Curves
|
|
32
|
+
*
|
|
33
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#elliptic-curves
|
|
34
|
+
*/
|
|
35
|
+
export declare enum COSECRV {
|
|
36
|
+
P256 = 1,
|
|
37
|
+
P384 = 2,
|
|
38
|
+
P521 = 3,
|
|
39
|
+
ED25519 = 6,
|
|
40
|
+
SECP256K1 = 8
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* COSE Key common and type-specific parameter labels.
|
|
44
|
+
*
|
|
45
|
+
* EC2 and RSA re-use the same numeric labels (-1, -2, -3) with different
|
|
46
|
+
* semantics, so this is a plain object instead of an enum to avoid
|
|
47
|
+
* duplicate-value violations.
|
|
48
|
+
*
|
|
49
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-common-parameters
|
|
50
|
+
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-type-parameters
|
|
51
|
+
*/
|
|
52
|
+
export declare const COSEKEYS: {
|
|
53
|
+
/** Key Type (common) */
|
|
54
|
+
readonly Kty: 1;
|
|
55
|
+
/** Algorithm (common) */
|
|
56
|
+
readonly Alg: 3;
|
|
57
|
+
/** EC2 / OKP: curve identifier */
|
|
58
|
+
readonly Crv: -1;
|
|
59
|
+
/** EC2: x-coordinate / OKP: public key */
|
|
60
|
+
readonly X: -2;
|
|
61
|
+
/** EC2: y-coordinate */
|
|
62
|
+
readonly Y: -3;
|
|
63
|
+
/** RSA: modulus n (shares numeric label with Crv) */
|
|
64
|
+
readonly N: -1;
|
|
65
|
+
/** RSA: exponent e (shares numeric label with X) */
|
|
66
|
+
readonly E: -2;
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=constants.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../src/webauthn/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,oBAAY,OAAO;IACjB,KAAK,KAAK;IACV,KAAK,KAAK;IACV,KAAK,MAAM;IACX,KAAK,MAAM;IACX,KAAK,MAAM;IACX,KAAK,MAAM;IACX,KAAK,MAAM;IACX,MAAM,MAAM;IACZ,KAAK,OAAO;IACZ,KAAK,OAAO;IACZ,KAAK,OAAO;IACZ,GAAG,SAAS;CACb;AAED;;;;GAIG;AACH,oBAAY,OAAO;IACjB,GAAG,IAAI;IACP,GAAG,IAAI;IACP,GAAG,IAAI;CACR;AAED;;;;GAIG;AACH,oBAAY,OAAO;IACjB,IAAI,IAAI;IACR,IAAI,IAAI;IACR,IAAI,IAAI;IACR,OAAO,IAAI;IACX,SAAS,IAAI;CACd;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ;IACnB,wBAAwB;;IAExB,yBAAyB;;IAGzB,kCAAkC;;IAElC,0CAA0C;;IAE1C,wBAAwB;;IAGxB,qDAAqD;;IAErD,oDAAoD;;CAE5C,CAAC"}
|