# @raytio/core

`@raytio/core` is a collection of low-level functions for using the Raytio API. It works in both the browser and a nodejs environment, although nodejs requires several polyfills (see below).

For a high-level and easy-to-use API, consider using [`@raytio/decrypt-helper`](https://npm.im/@raytio/decrypt-helper).

## Usage in nodejs

Nodejs does not support [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch), [WebCrypto](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API), or [atob](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/atob)/[btoa](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/atob), so these will need to be polyfilled. Older versions of nodejs (`<14.0.0`) also do not support [TextEncoder](https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder) or [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat).

If you use the high-level [`@raytio/decrypt-helper`](https://npm.im/@raytio/decrypt-helper) module, you don't need to worry about this.

If you wish to use `@raytio/core` directly, an example of configuring polyfills for nodejs is availble [here](https://gitlab.com/raytio/tools/decrypt-helper/-/blob/main/src/configureEnv.ts)

# API

## Table of contents

### Classes

- [LocalSecretRequiredError](classes/LocalSecretRequiredError.md)
- [PGPKeyExportError](classes/PGPKeyExportError.md)
- [PGPKeyImportError](classes/PGPKeyImportError.md)
- [UnknownKdfAlgorithmError](classes/UnknownKdfAlgorithmError.md)

### Interfaces

- [Argon2idConfig](interfaces/Argon2idConfig.md)
- [EncryptedPrivateKey](interfaces/EncryptedPrivateKey.md)
- [ExportPGPKeyOptions](interfaces/ExportPGPKeyOptions.md)
- [ExportedPGPKey](interfaces/ExportedPGPKey.md)
- [FormattedLocalSecret](interfaces/FormattedLocalSecret.md)
- [KdfResult](interfaces/KdfResult.md)
- [KeyValidationResult](interfaces/KeyValidationResult.md)
- [LocalSecretStorage](interfaces/LocalSecretStorage.md)
- [PGPKeyPair](interfaces/PGPKeyPair.md)
- [PGPKeyStorage](interfaces/PGPKeyStorage.md)
- [PGPPublicKeyProperties](interfaces/PGPPublicKeyProperties.md)
- [ParsedPGPKey](interfaces/ParsedPGPKey.md)
- [Pbkdf2Config](interfaces/Pbkdf2Config.md)
- [StoredLocalSecret](interfaces/StoredLocalSecret.md)
- [StoredPGPPrivateKey](interfaces/StoredPGPPrivateKey.md)

### Type Aliases

- [BadgeDefinition](#badgedefinition)
- [BadgeResult](#badgeresult)
- [BadgeState](#badgestate)
- [BadgeStateDisplay](#badgestatedisplay)
- [KdfConfig](#kdfconfig)
- [PGPKeyAlgorithm](#pgpkeyalgorithm)
- [SafeHarbourObj](#safeharbourobj)
- [SafeHarbourResult](#safeharbourresult)
- [ServerAA](#serveraa)
- [ServerRelationship](#serverrelationship)
- [VerDetails](#verdetails)

### Variables

- [AES\_GCM\_IV\_SIZE](#aes_gcm_iv_size)
- [DEFAULT\_ARGON2ID\_PARAMS](#default_argon2id_params)
- [KEY\_FINGERPRINT\_LENGTH](#key_fingerprint_length)
- [LOCAL\_SECRET\_CHARSET](#local_secret_charset)
- [LOCAL\_SECRET\_DB\_CONFIG](#local_secret_db_config)
- [LOCAL\_SECRET\_GROUP\_SIZE](#local_secret_group_size)
- [LOCAL\_SECRET\_SIZE](#local_secret_size)
- [PGP\_KEY\_DB\_CONFIG](#pgp_key_db_config)
- [TAG\_DENYLIST](#tag_denylist)

### Functions

- [base64ToUint8Array](#base64touint8array)
- [bytesToPem](#bytestopem)
- [calcSafeHarbourScore](#calcsafeharbourscore)
- [calculateScore](#calculatescore)
- [canonicalJsonify](#canonicaljsonify)
- [checkJsonSignature](#checkjsonsignature)
- [computeKeyFingerprint](#computekeyfingerprint)
- [constantTimeEqual](#constanttimeequal)
- [convertInstanceToRuleInput](#convertinstancetoruleinput)
- [convertServerRelationship](#convertserverrelationship)
- [createAA](#createaa)
- [createArgon2idConfig](#createargon2idconfig)
- [createHashedNId](#createhashednid)
- [createIndexedDBPGPKeyStorage](#createindexeddbpgpkeystorage)
- [createIndexedDBStorage](#createindexeddbstorage)
- [decryptPrivateKey](#decryptprivatekey)
- [decryptSharedData](#decryptshareddata)
- [deleteLocalSecret](#deletelocalsecret)
- [deletePGPPrivateKey](#deletepgpprivatekey)
- [deriveArgon2id](#deriveargon2id)
- [deriveKey](#derivekey)
- [derivePbkdf2](#derivepbkdf2)
- [deriveTwoSecretKdf](#derivetwosecretkdf)
- [encryptPrivateKey](#encryptprivatekey)
- [evaluateBadge](#evaluatebadge)
- [evaluateRule](#evaluaterule)
- [evaluateUserBadges](#evaluateuserbadges)
- [expandSchema](#expandschema)
- [exportPGPKeyToArmored](#exportpgpkeytoarmored)
- [extractPemType](#extractpemtype)
- [findSchemaLabel](#findschemalabel)
- [findSuitableLocale](#findsuitablelocale)
- [formatFingerprint](#formatfingerprint)
- [formatLocalSecret](#formatlocalsecret)
- [fromCognitoAttributes](#fromcognitoattributes)
- [generateDeviceId](#generatedeviceid)
- [generateLocalSecret](#generatelocalsecret)
- [generatePGPKeyPair](#generatepgpkeypair)
- [generateRandomBytes](#generaterandombytes)
- [generateSalt](#generatesalt)
- [getAADecryptor](#getaadecryptor)
- [getAAPublicKey](#getaapublickey)
- [getKdfVersion](#getkdfversion)
- [getLocalSecret](#getlocalsecret)
- [getLocalSecretRecord](#getlocalsecretrecord)
- [getMissingDataForInstance](#getmissingdataforinstance)
- [getNidFromUrn](#getnidfromurn)
- [getOrCreateDeviceId](#getorcreatedeviceid)
- [getOwnRealVerifications](#getownrealverifications)
- [getPGPPrivateKey](#getpgpprivatekey)
- [getPOVerification](#getpoverification)
- [getSomeoneElsesRealVerifications](#getsomeoneelsesrealverifications)
- [hasLocalSecret](#haslocalsecret)
- [hasPGPPrivateKey](#haspgpprivatekey)
- [hashPassword](#hashpassword)
- [importPrivateKey](#importprivatekey)
- [importPublicKey](#importpublickey)
- [isArgon2Available](#isargon2available)
- [isArgon2idConfig](#isargon2idconfig)
- [isArmoredPGPKey](#isarmoredpgpkey)
- [isConditionMet](#isconditionmet)
- [isEncrypted](#isencrypted)
- [isEncryptedFile](#isencryptedfile)
- [isPbkdf2Config](#ispbkdf2config)
- [isPemFormat](#ispemformat)
- [isScoreConfigValid](#isscoreconfigvalid)
- [isScoreResultValid](#isscoreresultvalid)
- [isValidFormattedLocalSecret](#isvalidformattedlocalsecret)
- [isValidLocalSecret](#isvalidlocalsecret)
- [maskLocalSecret](#masklocalsecret)
- [normalizePassword](#normalizepassword)
- [parseArmoredPGPKey](#parsearmoredpgpkey)
- [parseLocalSecret](#parselocalsecret)
- [pemToBytes](#pemtobytes)
- [repairDate](#repairdate)
- [requiresLocalSecret](#requireslocalsecret)
- [resolveSchemaExtensions](#resolveschemaextensions)
- [setArgon2Module](#setargon2module)
- [signData](#signdata)
- [signText](#signtext)
- [someEncrypted](#someencrypted)
- [sortSchemaProperties](#sortschemaproperties)
- [storeLocalSecret](#storelocalsecret)
- [storePGPPrivateKey](#storepgpprivatekey)
- [toCognitoAttributes](#tocognitoattributes)
- [uint8ArrayToBase64](#uint8arraytobase64)
- [validateImportedKey](#validateimportedkey)
- [verifySignature](#verifysignature)
- [verifyTextSignature](#verifytextsignature)
- [xorBytes](#xorbytes)

## Type Aliases

### BadgeDefinition

Ƭ **BadgeDefinition**: `CommonFields`<`BId`\> & { `display`: { `states`: `Record`<[`BadgeState`](#badgestate), [`BadgeStateDisplay`](#badgestatedisplay)\>  } ; `name`: `string` ; `ruleset`: `ScoreConfig`  }

Badge definition as stored in dsm_schema_badges

___

### BadgeResult

Ƭ **BadgeResult**: `Object`

Result of evaluating a badge for a user

#### Type declaration

| Name | Type |
| :------ | :------ |
| `badgeId` | `string` |
| `badgeName` | `string` |
| `diagnostics` | `ScoreResult`[``"diagnostics"``] |
| `display` | [`BadgeStateDisplay`](#badgestatedisplay) |
| `state` | [`BadgeState`](#badgestate) |

___

### BadgeState

Ƭ **BadgeState**: ``"not_met"`` \| ``"partially_met"`` \| ``"fully_met"``

Standard badge states - consistent across all badges

___

### BadgeStateDisplay

Ƭ **BadgeStateDisplay**: `Object`

Display configuration for a single badge state

#### Type declaration

| Name | Type |
| :------ | :------ |
| `color` | `string` |
| `icon` | `string` |
| `label` | `string` |

___

### KdfConfig

Ƭ **KdfConfig**: [`Pbkdf2Config`](interfaces/Pbkdf2Config.md) \| [`Argon2idConfig`](interfaces/Argon2idConfig.md)

Union type for all KDF configurations

___

### PGPKeyAlgorithm

Ƭ **PGPKeyAlgorithm**: ``"RSA-4096"`` \| ``"RSA-2048"``

Supported PGP key algorithms

___

### SafeHarbourObj

Ƭ **SafeHarbourObj**: `Partial`<`Record`<`SafeHarbourCode`, `string`[]\>\>

an object listing the `xId`s for each SafeHarbourCode

___

### SafeHarbourResult

Ƭ **SafeHarbourResult**: `Object`

the response from [calcSafeHarbourScore](#calcsafeharbourscore)

#### Type declaration

| Name | Type |
| :------ | :------ |
| `flags` | [`SafeHarbourObj`](#safeharbourobj) |
| `isSafe` | `boolean` |

___

### ServerAA

Ƭ **ServerAA**: `Omit`<`AA`, ``"a_id"``\> & { `id`: `AId`  }

___

### ServerRelationship

Ƭ **ServerRelationship**: `Omit`<`Relationship`, ``"p_id"`` \| ``"start"`` \| ``"end"``\> & { `from_id`: `NId` ; `id`: `PId` ; `to_i_id?`: `IId` \| ``null`` ; `to_id?`: `NId` \| ``null``  }

This type represents the relationship format returned by the Postgres API

___

### VerDetails

Ƭ **VerDetails**: `Object`

#### Type declaration

| Name | Type | Description |
| :------ | :------ | :------ |
| `expiryDate?` | `Date` | field only present for expired verifications |
| `sourceNId?` | `NId` | - |
| `verifiers` | `VerificationProvider`[] | - |

## Variables

### AES\_GCM\_IV\_SIZE

• `Const` **AES\_GCM\_IV\_SIZE**: ``12``

AES-GCM IV size in bytes

___

### DEFAULT\_ARGON2ID\_PARAMS

• `Const` **DEFAULT\_ARGON2ID\_PARAMS**: `Object`

Default Argon2id parameters (matching Bitwarden recommendations)

#### Type declaration

| Name | Type |
| :------ | :------ |
| `iterations` | ``3`` |
| `memory` | ``65536`` |
| `parallelism` | ``4`` |

___

### KEY\_FINGERPRINT\_LENGTH

• `Const` **KEY\_FINGERPRINT\_LENGTH**: ``40``

Key fingerprint length (hex characters)

___

### LOCAL\_SECRET\_CHARSET

• `Const` **LOCAL\_SECRET\_CHARSET**: ``"23456789ABCDEFGHJKLMNPQRSTUVWXYZ"``

Character set for LocalSecret display format

Excludes ambiguous characters: 0, 1, I, O

___

### LOCAL\_SECRET\_DB\_CONFIG

• `Const` **LOCAL\_SECRET\_DB\_CONFIG**: `Object`

IndexedDB configuration for LocalSecret storage

#### Type declaration

| Name | Type |
| :------ | :------ |
| `name` | ``"raytio-secrets"`` |
| `storeName` | ``"local-secrets"`` |
| `version` | ``1`` |

___

### LOCAL\_SECRET\_GROUP\_SIZE

• `Const` **LOCAL\_SECRET\_GROUP\_SIZE**: ``6``

Number of characters per group in formatted display

___

### LOCAL\_SECRET\_SIZE

• `Const` **LOCAL\_SECRET\_SIZE**: ``32``

LocalSecret size in bytes (256 bits)

___

### PGP\_KEY\_DB\_CONFIG

• `Const` **PGP\_KEY\_DB\_CONFIG**: `Object`

IndexedDB configuration for PGP key storage

#### Type declaration

| Name | Type |
| :------ | :------ |
| `name` | ``"raytio-pgp-keys"`` |
| `storeName` | ``"private-keys"`` |
| `version` | ``1`` |

___

### TAG\_DENYLIST

• `Const` **TAG\_DENYLIST**: `SchemaTag`[]

## Functions

### base64ToUint8Array

▸ **base64ToUint8Array**(`base64`): `Uint8Array`

Convert a base64 string to Uint8Array

#### Parameters

| Name | Type |
| :------ | :------ |
| `base64` | `string` |

#### Returns

`Uint8Array`

___

### bytesToPem

▸ **bytesToPem**(`bytes`, `type`): `string`

Convert raw bytes to PEM format

Encodes the bytes as base64 and wraps with PEM headers.
Base64 content is wrapped at 64 characters per line per RFC 7468.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `bytes` | `Uint8Array` | Raw bytes to encode |
| `type` | `string` | PEM type (e.g., "PUBLIC KEY", "PRIVATE KEY") |

#### Returns

`string`

PEM-formatted string

___

### calcSafeHarbourScore

▸ **calcSafeHarbourScore**(`data`): `Promise`<[`SafeHarbourResult`](#safeharbourresult)\>

The Safe Harbour Score indidicates whether a person's identity has been verified
to the extent requried for Safe Harbour Compliance. This requires multiple verifications
from different sources. For information, refer to the
[Raytio Documentation](https://dev-docs.rayt.io/docs/features/pep-checks).

#### Parameters

| Name | Type |
| :------ | :------ |
| `data` | `Object` |
| `data.person` | `ProfileObject` |
| `data.profileObjects` | `ProfileObject`[] |
| `data.realVers` | `RealVer`[] |
| `data.getSchema` | (`schemaName`: `SchemaName`) => `Promise`<`Schema`\> |

#### Returns

`Promise`<[`SafeHarbourResult`](#safeharbourresult)\>

___

### calculateScore

▸ **calculateScore**(`ruleConfig`, `ruleInput`): `Promise`<`ScoreResult`\>

the main function to calculate a score and category.
Might throw an error.

#### Parameters

| Name | Type |
| :------ | :------ |
| `ruleConfig` | `ScoreConfig` |
| `ruleInput` | `RuleData` |

#### Returns

`Promise`<`ScoreResult`\>

___

### canonicalJsonify

▸ **canonicalJsonify**(`object`): `string`

Creates a canonical JSON string representation of an object.

Spec compliant, and matches
https://gitlab.com/raytio/mono/-/blob/devo/common/signing/signing/canonical_json.py

#### Parameters

| Name | Type |
| :------ | :------ |
| `object` | `unknown` |

#### Returns

`string`

___

### checkJsonSignature

▸ **checkJsonSignature**(`data`, `signature`, `keyId`): `Promise`<`boolean`\>

checks that a json object was signed by the provided signature. Unless you're
dealing with bundled verifications, you should use `getOwnRealVerifications`
or `getSomeoneElsesRealVerifications` instead.

#### Parameters

| Name | Type |
| :------ | :------ |
| `data` | `unknown` |
| `signature` | `string` |
| `keyId` | `undefined` \| `string` |

#### Returns

`Promise`<`boolean`\>

___

### computeKeyFingerprint

▸ **computeKeyFingerprint**(`publicKeyBytes`): `Promise`<`string`\>

Compute SHA-256 fingerprint of public key bytes

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `publicKeyBytes` | `Uint8Array` | Raw public key bytes (SPKI format) |

#### Returns

`Promise`<`string`\>

First 40 hex characters of SHA-256 hash

___

### constantTimeEqual

▸ **constantTimeEqual**(`a`, `b`): `boolean`

Constant-time comparison of two byte arrays

Prevents timing attacks when comparing secrets.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `a` | `Uint8Array` | First byte array |
| `b` | `Uint8Array` | Second byte array |

#### Returns

`boolean`

true if arrays are equal

___

### convertInstanceToRuleInput

▸ **convertInstanceToRuleInput**(`POs`, `realVers`, `getSchema`): `Promise`<`RuleData`\>

#### Parameters

| Name | Type |
| :------ | :------ |
| `POs` | `ProfileObject`[] |
| `realVers` | `RealVer`[] |
| `getSchema` | (`schemaName`: `SchemaName`) => `Promise`<`Schema`\> |

#### Returns

`Promise`<`RuleData`\>

___

### convertServerRelationship

▸ **convertServerRelationship**(`serverRelationship`): `Relationship`

Converts relationship type used by the server into the (Urn format) type used by the client

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `serverRelationship` | [`ServerRelationship`](#serverrelationship) | relationship type used in the server |

#### Returns

`Relationship`

a Relationship (client-side type) that is equivalent to the inputted serverRelationship value

___

### createAA

▸ **createAA**(`«destructured»`): `Promise`<`AA`\>

Creates an Access Application and associated public+private keys.

The user must be part of an organization, and you need to include the `orgId`.

You must also supply an apiToken and an instance of the maxcryptor for that user,
as well as the `userDoc` data which is stored in the user's cognito attributes.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `apiToken` | `string` |
| › `apiUrl` | `string` |
| › `application` | `Omit`<`AA`, ``"a_id"``\> |
| › `maxcryptor` | `DataEncryptorI` |
| › `userDoc` | `UserDoc` |

#### Returns

`Promise`<`AA`\>

___

### createArgon2idConfig

▸ **createArgon2idConfig**(`salt`, `params?`): [`Argon2idConfig`](interfaces/Argon2idConfig.md)

Create a new Argon2id configuration

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `salt` | `string` | Base64 encoded salt (optional, will generate if not provided) |
| `params?` | `Partial`<`Pick`<[`Argon2idConfig`](interfaces/Argon2idConfig.md), ``"iterations"`` \| ``"memory"`` \| ``"parallelism"``\>\> | Optional custom parameters |

#### Returns

[`Argon2idConfig`](interfaces/Argon2idConfig.md)

Argon2idConfig ready for storage

___

### createHashedNId

▸ **createHashedNId**(`nId`, `aId`): `NId`

the API returns hashed NIds in a separate field,
which breaks the whole app. So, we move the hashed ID into
the normal `n_id` field, and use a different format.

This was first introduced in #1048

#### Parameters

| Name | Type |
| :------ | :------ |
| `nId` | `NId` |
| `aId` | `AId` |

#### Returns

`NId`

___

### createIndexedDBPGPKeyStorage

▸ **createIndexedDBPGPKeyStorage**(): [`PGPKeyStorage`](interfaces/PGPKeyStorage.md)

Create a PGPKeyStorage implementation using IndexedDB

#### Returns

[`PGPKeyStorage`](interfaces/PGPKeyStorage.md)

___

### createIndexedDBStorage

▸ **createIndexedDBStorage**(): [`LocalSecretStorage`](interfaces/LocalSecretStorage.md)

Create a LocalSecretStorage implementation using IndexedDB

#### Returns

[`LocalSecretStorage`](interfaces/LocalSecretStorage.md)

___

### decryptPrivateKey

▸ **decryptPrivateKey**(`encryptedPrivateKey`, `iv`, `kek`): `Promise`<`Uint8Array`\>

Decrypt private key bytes with the user's KEK using AES-GCM

**`Throws`**

Error if decryption fails (wrong key or tampered data)

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `encryptedPrivateKey` | `Uint8Array` | AES-GCM encrypted private key bytes |
| `iv` | `Uint8Array` | 12-byte initialization vector used during encryption |
| `kek` | `Uint8Array` | 32-byte Key Encryption Key from 2SKD |

#### Returns

`Promise`<`Uint8Array`\>

Decrypted private key bytes (PKCS8 format)

___

### decryptSharedData

▸ **decryptSharedData**(`«destructured»`): `Promise`<{ `applicationDecryptor`: `ApplicationDataEncryptorI` ; `instance`: `Instance`  }\>

Decrypts any encrypted properties included in the supplied `instanceData`.
If nothing is encrypted the supplied `instanceData` is returned.

It will reject if there are keys missing for any encrypted properties, or
if the encrypted data is invalid. If you don't want it to reject, you can
supply a `onCorruptedData` function which returns a value to use instead.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `apiToken` | `string` |
| › `apiUrl` | `string` |
| › `instanceData` | `Instance` |
| › `maxcryptor` | `DataEncryptorI` |
| › `onCorruptedData?` | (`fieldName`: `string`, `fieldValue`: `Encrypted`, `error`: `Error`) => `any` |

#### Returns

`Promise`<{ `applicationDecryptor`: `ApplicationDataEncryptorI` ; `instance`: `Instance`  }\>

a copy of `instanceData` with all properties decrypted.

___

### deleteLocalSecret

▸ **deleteLocalSecret**(`userId`): `Promise`<`void`\>

Delete a LocalSecret from IndexedDB

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<`void`\>

___

### deletePGPPrivateKey

▸ **deletePGPPrivateKey**(`userId`): `Promise`<`void`\>

Delete an encrypted PGP private key from IndexedDB

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<`void`\>

___

### deriveArgon2id

▸ **deriveArgon2id**(`password`, `config`): `Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

Derive a key using Argon2id

**`Throws`**

Error if argon2 module is not available

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `password` | `string` | User's password (will be normalized) |
| `config` | [`Argon2idConfig`](interfaces/Argon2idConfig.md) | Argon2id configuration from Cognito attributes |

#### Returns

`Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

KdfResult containing the derived 32-byte key

___

### deriveKey

▸ **deriveKey**(`password`, `config`, `localSecret?`): `Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

Derive a key using the appropriate KDF based on configuration

This is the main entry point for key derivation. It automatically
selects the correct algorithm based on the config.

**`Throws`**

LocalSecretRequiredError if LocalSecret is required but not provided

**`Throws`**

UnknownKdfAlgorithmError if the algorithm is not recognized

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `password` | `string` | User's password |
| `config` | [`KdfConfig`](#kdfconfig) | KDF configuration from Cognito attributes |
| `localSecret?` | ``null`` \| `Uint8Array` | Optional LocalSecret for 2SKD (required for Argon2id with requires_local_secret) |

#### Returns

`Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

KdfResult containing the derived key

___

### derivePbkdf2

▸ **derivePbkdf2**(`password`, `config`): `Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

Derive a key using PBKDF2

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `password` | `string` | User's password |
| `config` | [`Pbkdf2Config`](interfaces/Pbkdf2Config.md) | PBKDF2 configuration from Cognito attributes |

#### Returns

`Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

KdfResult containing the derived 32-byte key

___

### deriveTwoSecretKdf

▸ **deriveTwoSecretKdf**(`password`, `config`, `localSecret`): `Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

Derive KEK using Two-Secret Key Derivation

Combines:
1. Password → Argon2id → 32 bytes
2. LocalSecret → 32 bytes
3. XOR(1, 2) → KEK

**`Throws`**

LocalSecretRequiredError if localSecret is not provided but required

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `password` | `string` | User's password |
| `config` | [`Argon2idConfig`](interfaces/Argon2idConfig.md) | Argon2id configuration |
| `localSecret` | `undefined` \| ``null`` \| `Uint8Array` | Device-bound LocalSecret (32 bytes) |

#### Returns

`Promise`<[`KdfResult`](interfaces/KdfResult.md)\>

KdfResult containing the derived KEK

___

### encryptPrivateKey

▸ **encryptPrivateKey**(`privateKeyBytes`, `kek`): `Promise`<[`EncryptedPrivateKey`](interfaces/EncryptedPrivateKey.md)\>

Encrypt private key bytes with the user's KEK using AES-GCM

Uses a random 12-byte IV for each encryption operation.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `privateKeyBytes` | `Uint8Array` | Raw private key bytes (PKCS8 format) |
| `kek` | `Uint8Array` | 32-byte Key Encryption Key from 2SKD |

#### Returns

`Promise`<[`EncryptedPrivateKey`](interfaces/EncryptedPrivateKey.md)\>

Encrypted private key and IV

___

### evaluateBadge

▸ **evaluateBadge**(`badge`, `ruleData`): `Promise`<[`BadgeResult`](#badgeresult)\>

Evaluate a single badge definition against user data.
Thin wrapper around calculateScore() -- threshold names map to badge states.

#### Parameters

| Name | Type |
| :------ | :------ |
| `badge` | [`BadgeDefinition`](#badgedefinition) |
| `ruleData` | `RuleData` |

#### Returns

`Promise`<[`BadgeResult`](#badgeresult)\>

___

### evaluateRule

▸ **evaluateRule**(`rule`, `data`): `Object`

evaluates an individual rule, normally you should use [calculateScore](#calculatescore)

#### Parameters

| Name | Type |
| :------ | :------ |
| `rule` | `ScoreRule` |
| `data` | `RuleData` |

#### Returns

`Object`

| Name | Type |
| :------ | :------ |
| `passed` | `boolean` |
| `score` | `number` |

___

### evaluateUserBadges

▸ **evaluateUserBadges**(`badges`, `ruleData`): `Promise`<[`BadgeResult`](#badgeresult)[]\>

Evaluate all active badge definitions against user data.

#### Parameters

| Name | Type |
| :------ | :------ |
| `badges` | [`BadgeDefinition`](#badgedefinition)[] |
| `ruleData` | `RuleData` |

#### Returns

`Promise`<[`BadgeResult`](#badgeresult)[]\>

___

### expandSchema

▸ **expandSchema**(`wrappedSchema`, `allUnexpandedSchemas`, `userLocales`, `fndI18nEntries?`): `Schema`

This is the main function to transform a schema from
the JSON that the API returns, into a `Schema` object that's useful
to the client.

#### Parameters

| Name | Type |
| :------ | :------ |
| `wrappedSchema` | `WrappedSchema` |
| `allUnexpandedSchemas` | `WrappedSchema`[] |
| `userLocales` | readonly `string`[] |
| `fndI18nEntries?` | `FndI18nEntry`[] |

#### Returns

`Schema`

___

### exportPGPKeyToArmored

▸ **exportPGPKeyToArmored**(`privateKeyBytes`, `options?`): `Promise`<[`ExportedPGPKey`](interfaces/ExportedPGPKey.md)\>

Export a PKCS8 private key to OpenPGP armored format

This function converts existing PKCS8 RSA key material to OpenPGP format,
preserving the original cryptographic material. The exported key can be
used with GPG, GitHub, and other OpenPGP-compatible tools.

**`Throws`**

PGPKeyExportError if export fails

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `privateKeyBytes` | `Uint8Array` | PKCS8 encoded private key bytes |
| `options` | [`ExportPGPKeyOptions`](interfaces/ExportPGPKeyOptions.md) | Export options (passphrase, userIds, date) |

#### Returns

`Promise`<[`ExportedPGPKey`](interfaces/ExportedPGPKey.md)\>

Armored private and public keys with fingerprint

___

### extractPemType

▸ **extractPemType**(`pem`): `string` \| ``null``

Extract the type from a PEM-formatted string

For example, extracts "PUBLIC KEY" from:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `pem` | `string` | PEM-formatted string |

#### Returns

`string` \| ``null``

The type string (e.g., "PUBLIC KEY", "PRIVATE KEY"), or null if not valid PEM

___

### findSchemaLabel

▸ **findSchemaLabel**(`labels`): `undefined` \| `SchemaName`

Finds the label (on a profile object) which is the schema name

#### Parameters

| Name | Type |
| :------ | :------ |
| `labels` | `undefined` \| `string`[] |

#### Returns

`undefined` \| `SchemaName`

___

### findSuitableLocale

▸ **findSuitableLocale**(`options`, `langs`): `undefined` \| `string`

Selects the most suitable locale to use from a list of options.
Returns undefined if there is no language that the user speaks.

Priority order:
1. Exact full locale match (e.g., user has en-NZ, schema has en-NZ)
2. Base language match (e.g., user has en-US, schema has en)
3. Any locale with matching base language (e.g., user has de-DE, schema has de-AT)

#### Parameters

| Name | Type |
| :------ | :------ |
| `options` | `string`[] |
| `langs` | readonly `string`[] |

#### Returns

`undefined` \| `string`

___

### formatFingerprint

▸ **formatFingerprint**(`fingerprint`): `string`

Format a key fingerprint for display

Converts to uppercase and groups into 4-character blocks separated by spaces.
For example: "abcd1234efgh5678" becomes "ABCD 1234 EFGH 5678"

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `fingerprint` | `string` | Raw fingerprint string (typically 40 hex characters) |

#### Returns

`string`

Formatted fingerprint string

___

### formatLocalSecret

▸ **formatLocalSecret**(`secret`): [`FormattedLocalSecret`](interfaces/FormattedLocalSecret.md)

Format a LocalSecret for human-readable display

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `secret` | `Uint8Array` | The 32-byte LocalSecret |

#### Returns

[`FormattedLocalSecret`](interfaces/FormattedLocalSecret.md)

Formatted LocalSecret with grouped characters

___

### fromCognitoAttributes

▸ **fromCognitoAttributes**(`attributes`): `UserDoc`

This function converts Cognito's userAttributes into a maxcryptor UserDoc.
The userAttributes come from `const attributes = await Auth.userAttributes(user)`

#### Parameters

| Name | Type |
| :------ | :------ |
| `attributes` | `ICognitoUserAttributeData`[] |

#### Returns

`UserDoc`

___

### generateDeviceId

▸ **generateDeviceId**(): `string`

Generate a unique device ID

Used to identify devices for LocalSecret management.

#### Returns

`string`

UUID v4 string

___

### generateLocalSecret

▸ **generateLocalSecret**(): `Uint8Array`

Generate a new LocalSecret

Uses the Web Crypto API's getRandomValues for cryptographically
secure random number generation.

#### Returns

`Uint8Array`

32-byte (256-bit) random LocalSecret

___

### generatePGPKeyPair

▸ **generatePGPKeyPair**(): `Promise`<[`PGPKeyPair`](interfaces/PGPKeyPair.md)\>

Generate an RSA 4096-bit key pair for digital signatures

#### Returns

`Promise`<[`PGPKeyPair`](interfaces/PGPKeyPair.md)\>

Generated key pair with PEM public key and raw private key bytes

___

### generateRandomBytes

▸ **generateRandomBytes**(`length`): `Uint8Array`

Generate cryptographically secure random bytes

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `length` | `number` | Number of bytes to generate |

#### Returns

`Uint8Array`

Random bytes

___

### generateSalt

▸ **generateSalt**(): `string`

Generate a random salt for key derivation

#### Returns

`string`

16-byte random salt as base64 string

___

### getAADecryptor

▸ **getAADecryptor**(`«destructured»`): `Promise`<{ `decryptor`: `ApplicationEncryptor` ; `publicKeyId`: `KId`  }\>

Fetchs the public and private keys for an Access Application, then initializes
the [https://npm.im/@raytio/maxcryptor|Maxcryptor](https://npm.im/@raytio/maxcryptor|Maxcryptor)'s `ApplicationEncryptor`.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `aId` | `AId` |
| › `apiToken` | `string` |
| › `apiUrl` | `string` |
| › `maxcryptor` | `DataEncryptorI` |

#### Returns

`Promise`<{ `decryptor`: `ApplicationEncryptor` ; `publicKeyId`: `KId`  }\>

an `ApplicationEncryptor` and the public key of the Access Application

___

### getAAPublicKey

▸ **getAAPublicKey**(`«destructured»`): `Promise`<`PublicKeyNode`\>

Fetches the Public Key Information for an Access Application

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `aId` | `AId` |
| › `apiToken?` | `string` |
| › `apiUrl` | `string` |

#### Returns

`Promise`<`PublicKeyNode`\>

the id and Key information of the Applications Public Key

___

### getKdfVersion

▸ **getKdfVersion**(`config`): `number`

Get the KDF version from configuration

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `config` | [`KdfConfig`](#kdfconfig) | KDF configuration |

#### Returns

`number`

Version number (1 for PBKDF2, 2 for Argon2id with 2SKD)

___

### getLocalSecret

▸ **getLocalSecret**(`userId`): `Promise`<`Uint8Array` \| ``null``\>

Retrieve a LocalSecret from IndexedDB

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<`Uint8Array` \| ``null``\>

The LocalSecret or null if not found

___

### getLocalSecretRecord

▸ **getLocalSecretRecord**(`userId`): `Promise`<[`StoredLocalSecret`](interfaces/StoredLocalSecret.md) \| ``null``\>

Get the stored LocalSecret record (including metadata)

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<[`StoredLocalSecret`](interfaces/StoredLocalSecret.md) \| ``null``\>

The full storage record or null

___

### getMissingDataForInstance

▸ **getMissingDataForInstance**(`«destructured»`): `Promise`<`Instance`\>

the new API doesn't return the whole instance at once,
so we have to make several additional API requests.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `apiToken` | `string` |
| › `apiUrl` | `string` |
| › `instanceWithoutData` | `InstanceWithoutData` |

#### Returns

`Promise`<`Instance`\>

___

### getNidFromUrn

▸ **getNidFromUrn**<`IDType`\>(`urn`): `IDType`

two overloads - if you provide undefined, you might get undefined back

#### Type parameters

| Name | Type |
| :------ | :------ |
| `IDType` | `NId` |

#### Parameters

| Name | Type |
| :------ | :------ |
| `urn` | `Urn` |

#### Returns

`IDType`

▸ **getNidFromUrn**<`IDType`\>(`urn`): `undefined` \| `IDType`

two overloads - if you provide undefined, you might get undefined back

#### Type parameters

| Name | Type |
| :------ | :------ |
| `IDType` | `NId` |

#### Parameters

| Name | Type |
| :------ | :------ |
| `urn` | `undefined` \| `Urn` |

#### Returns

`undefined` \| `IDType`

___

### getOrCreateDeviceId

▸ **getOrCreateDeviceId**(): `Promise`<`string`\>

Get or create a unique device ID

The device ID is stored in localStorage for persistence.

#### Returns

`Promise`<`string`\>

___

### getOwnRealVerifications

▸ **getOwnRealVerifications**(`«destructured»`): `Promise`<`RealVer`[]\>

Given a list of verifications and decrypted profile objects, this function
locally verifies the credibility of the signatures in the verifications.

This function does NOT call the API, except to fetch the public key.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `profileObjects` | `ProfileObject`[] |
| › `userId` | `UId` |
| › `verifications` | `Verification`[] |

#### Returns

`Promise`<`RealVer`[]\>

a list of authentic RealVer

___

### getPGPPrivateKey

▸ **getPGPPrivateKey**(`userId`): `Promise`<[`StoredPGPPrivateKey`](interfaces/StoredPGPPrivateKey.md) \| ``null``\>

Retrieve an encrypted PGP private key from IndexedDB

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<[`StoredPGPPrivateKey`](interfaces/StoredPGPPrivateKey.md) \| ``null``\>

The encrypted private key record or null if not found

___

### getPOVerification

▸ **getPOVerification**(`«destructured»`): `Object`

Determines the verification status of a profile object, and its individual fields.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Object` |
| › `PO` | `ProfileObject` \| `ProfileObjectForUpload` |
| › `realVers` | `RealVer`[] |
| › `schema` | `Schema` |

#### Returns

`Object`

| Name | Type |
| :------ | :------ |
| `details` | [`VerDetails`](#verdetails) |
| `fieldVerifications` | `Record`<`string`, `FieldVerification`\> |
| `status` | `POVerification` |

___

### getSomeoneElsesRealVerifications

▸ **getSomeoneElsesRealVerifications**(`«destructured»`): `Promise`<`RealVer`[]\>

Given a list of verifications and decrypted profile objects, this function calls
the Raytio API to verify the credibility of these verifications, returning only valid
verifications.

❗ prefer `getOwnRealVerifications` if the data to be verified belongs to the current user.

#### Parameters

| Name | Type |
| :------ | :------ |
| `«destructured»` | `Props` |

#### Returns

`Promise`<`RealVer`[]\>

a list of fileNames/values that are verified.

___

### hasLocalSecret

▸ **hasLocalSecret**(`userId`): `Promise`<`boolean`\>

Check if a LocalSecret exists for a user

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<`boolean`\>

true if a LocalSecret exists

___

### hasPGPPrivateKey

▸ **hasPGPPrivateKey**(`userId`): `Promise`<`boolean`\>

Check if an encrypted PGP private key exists for a user

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |

#### Returns

`Promise`<`boolean`\>

true if a key exists

___

### hashPassword

▸ **hashPassword**(`password`): `Promise`<`string`\>

**`Deprecated`**

legacy feature, see #1252

AWS Cognito never gets the raw password. We send them
a hashed verison using PBKDF2 with SHA-256 and 10,000
iterations.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `password` | `string` | The raw password |

#### Returns

`Promise`<`string`\>

Promise resolving to the hashed password

___

### importPrivateKey

▸ **importPrivateKey**(`privateKeyBytes`): `Promise`<`CryptoKey`\>

Import private key bytes as a CryptoKey for RSA-PSS signing

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `privateKeyBytes` | `Uint8Array` | Private key in PKCS8 format |

#### Returns

`Promise`<`CryptoKey`\>

CryptoKey configured for RSA-PSS signing with SHA-256

___

### importPublicKey

▸ **importPublicKey**(`publicKeyPem`): `Promise`<`CryptoKey`\>

Import a PEM-encoded public key as a CryptoKey for RSA-PSS verification

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `publicKeyPem` | `string` | Public key in PEM format (SPKI) |

#### Returns

`Promise`<`CryptoKey`\>

CryptoKey configured for RSA-PSS verification with SHA-256

___

### isArgon2Available

▸ **isArgon2Available**(): `boolean`

Check if Argon2 module is available

#### Returns

`boolean`

___

### isArgon2idConfig

▸ **isArgon2idConfig**(`config`): config is Argon2idConfig

Type guard for Argon2id config

#### Parameters

| Name | Type |
| :------ | :------ |
| `config` | [`KdfConfig`](#kdfconfig) |

#### Returns

config is Argon2idConfig

___

### isArmoredPGPKey

▸ **isArmoredPGPKey**(`input`): `boolean`

Check if a string looks like an armored PGP key

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `input` | `string` | String to check |

#### Returns

`boolean`

true if it appears to be armored PGP format

___

### isConditionMet

▸ **isConditionMet**(`condition`, `formValues`): `boolean`

Checks all other form values in case any have a
trigger value that makes this field required.

**`Example`**

```json
[
  { "if": { "age": [17, 18], "city": ["Taupō"] } },
  { "if": { "age": [19, 20] } }
]
```

This means `[(age=17 OR age=18) AND (city=Taupō)] OR [(age=19 OR age=20)]`

#### Parameters

| Name | Type |
| :------ | :------ |
| `condition` | `Record`<`string`, `ConditionValue`[]\> |
| `formValues` | `Record`<`string`, `unknown`\> |

#### Returns

`boolean`

___

### isEncrypted

▸ **isEncrypted**(`value`): value is Encrypted

Determines where the input is an encrypted Raytio object

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `value` | `unknown` | anything |

#### Returns

value is Encrypted

true or false depending on whether the input is an encrypted Raytio object

___

### isEncryptedFile

▸ **isEncryptedFile**(`value`): value is Encrypted

Determines where the input is an encrypted Raytio file

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `value` | `unknown` | anything |

#### Returns

value is Encrypted

true or false depending on whether the input is an encrypted Raytio file

___

### isPbkdf2Config

▸ **isPbkdf2Config**(`config`): config is Pbkdf2Config

Type guard for PBKDF2 config

#### Parameters

| Name | Type |
| :------ | :------ |
| `config` | [`KdfConfig`](#kdfconfig) |

#### Returns

config is Pbkdf2Config

___

### isPemFormat

▸ **isPemFormat**(`input`): `boolean`

Check if a string is in valid PEM format

PEM format requires:
- A BEGIN header with a type (e.g., "-----BEGIN PUBLIC KEY-----")
- Base64-encoded content
- An END footer with matching type (e.g., "-----END PUBLIC KEY-----")

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `input` | `string` | String to check |

#### Returns

`boolean`

true if the string is valid PEM format, false otherwise

___

### isScoreConfigValid

▸ **isScoreConfigValid**(`x`): x is ScoreConfig

determines whether a `ScoreConfig` object is valid

#### Parameters

| Name | Type |
| :------ | :------ |
| `x` | `unknown` |

#### Returns

x is ScoreConfig

___

### isScoreResultValid

▸ **isScoreResultValid**(`x`): x is ScoreResult

determines whether a `ScoreResult` object is valid

#### Parameters

| Name | Type |
| :------ | :------ |
| `x` | `unknown` |

#### Returns

x is ScoreResult

___

### isValidFormattedLocalSecret

▸ **isValidFormattedLocalSecret**(`formatted`): `boolean`

Validate a formatted LocalSecret string

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `formatted` | `string` | The formatted LocalSecret string |

#### Returns

`boolean`

true if valid, false otherwise

___

### isValidLocalSecret

▸ **isValidLocalSecret**(`localSecret`): localSecret is Uint8Array

Verify that a LocalSecret is valid

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `localSecret` | `undefined` \| ``null`` \| `Uint8Array` | The LocalSecret to verify |

#### Returns

localSecret is Uint8Array

true if valid

___

### maskLocalSecret

▸ **maskLocalSecret**(`formatted`): `string`

Mask a LocalSecret for partial display

Shows only the first and last groups, masking the middle.
Example: A7K2M9-******-******-******-******-V6Z4C1

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `formatted` | `string` | The formatted LocalSecret |

#### Returns

`string`

Masked version for display

___

### normalizePassword

▸ **normalizePassword**(`password`): `string`

Normalize password for key derivation

Applies NFKD normalization and trims whitespace.
This ensures consistent key derivation across platforms.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `password` | `string` | Raw password input |

#### Returns

`string`

Normalized password string

___

### parseArmoredPGPKey

▸ **parseArmoredPGPKey**(`armoredKey`, `passphrase?`): `Promise`<[`ParsedPGPKey`](interfaces/ParsedPGPKey.md)\>

Parse an armored PGP private key

**`Throws`**

PGPKeyImportError if parsing fails

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `armoredKey` | `string` | Armored PGP private key string |
| `passphrase?` | `string` | Optional passphrase if key is encrypted |

#### Returns

`Promise`<[`ParsedPGPKey`](interfaces/ParsedPGPKey.md)\>

Parsed key data

___

### parseLocalSecret

▸ **parseLocalSecret**(`formatted`): `Uint8Array`

Parse a formatted LocalSecret back to bytes

Handles various input formats:
- With dashes: A7K2M9-X4P8N3-...
- Without dashes: A7K2M9X4P8N3...
- With spaces: A7K2M9 X4P8N3 ...
- Lowercase: a7k2m9-x4p8n3-...

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `formatted` | `string` | The formatted LocalSecret string |

#### Returns

`Uint8Array`

The 32-byte LocalSecret

___

### pemToBytes

▸ **pemToBytes**(`pem`): `Uint8Array`

Convert PEM-formatted string to raw bytes

Extracts the base64 content from between the PEM headers and decodes it.

**`Throws`**

Error if the input is not valid PEM format

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `pem` | `string` | PEM-formatted string |

#### Returns

`Uint8Array`

Raw bytes as Uint8Array

___

### repairDate

▸ **repairDate**(`date`): `Date`

repairs broken ISO dates into valid JS date objects

#### Parameters

| Name | Type |
| :------ | :------ |
| `date` | `string` \| `Date` |

#### Returns

`Date`

___

### requiresLocalSecret

▸ **requiresLocalSecret**(`config`): `boolean`

Check if a KDF configuration requires LocalSecret

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `config` | [`KdfConfig`](#kdfconfig) | KDF configuration |

#### Returns

`boolean`

true if LocalSecret is required

___

### resolveSchemaExtensions

▸ **resolveSchemaExtensions**(`schemas`): `WrappedSchema`[]

Resolves schema extensions by deep-merging base schemas into extension schemas.

When a schema has `extends_schema_name` set, the base schema is looked up
from the already-fetched schemas and deep-merged with the extension.
The extension wins on conflict.

Design constraints:
- Single-level only: a base schema must not itself be an extension
- Same tenant only: enforced at DB level
- `extends_schema_version`: if set, matches against `schema_version`;
  if null, the base's `version_current` entry is used (already in the list)

#### Parameters

| Name | Type |
| :------ | :------ |
| `schemas` | `WrappedSchema`[] |

#### Returns

`WrappedSchema`[]

___

### setArgon2Module

▸ **setArgon2Module**(`module`): `void`

Set the Argon2 module reference

This must be called before using deriveArgon2id.
The module is passed in from packages/client where argon2-browser is imported.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `module` | `Argon2Module` | The argon2-browser module |

#### Returns

`void`

___

### signData

▸ **signData**(`data`, `privateKey`): `Promise`<`Uint8Array`\>

Sign raw bytes with an RSA-PSS private key

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `data` | `Uint8Array` | Data to sign as Uint8Array |
| `privateKey` | `CryptoKey` | CryptoKey configured for RSA-PSS signing |

#### Returns

`Promise`<`Uint8Array`\>

Signature bytes (512 bytes for RSA-4096)

___

### signText

▸ **signText**(`text`, `privateKey`): `Promise`<`string`\>

Sign text and return base64-encoded signature

Convenience wrapper that encodes text to UTF-8 bytes before signing.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `text` | `string` | Text to sign |
| `privateKey` | `CryptoKey` | CryptoKey configured for RSA-PSS signing |

#### Returns

`Promise`<`string`\>

Base64-encoded signature string

___

### someEncrypted

▸ **someEncrypted**<`T`\>(`...args`): `number`

Given a profile object's properties, returns the number
of properties that are encryted.

#### Type parameters

| Name | Type |
| :------ | :------ |
| `T` | extends `object` |

#### Parameters

| Name | Type |
| :------ | :------ |
| `...args` | [obj: T] |

#### Returns

`number`

___

### sortSchemaProperties

▸ **sortSchemaProperties**(`properties`, `groupOrder?`): `Section`[]

Schema properties are an object, so they need to be converted into an
array, grouped by the group tag, and then sorted based on the `priority`
attribute within their group.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `properties` | `Record`<`string`, `SchemaField`\> | The schema properties to sort |
| `groupOrder?` | `string`[] | Optional array specifying the order of groups. Groups not in this array will appear after ordered groups. |

#### Returns

`Section`[]

___

### storeLocalSecret

▸ **storeLocalSecret**(`userId`, `secret`): `Promise`<`void`\>

Store a LocalSecret in IndexedDB

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `userId` | `string` | User's Cognito sub |
| `secret` | `Uint8Array` | The 32-byte LocalSecret |

#### Returns

`Promise`<`void`\>

___

### storePGPPrivateKey

▸ **storePGPPrivateKey**(`record`): `Promise`<`void`\>

Store an encrypted PGP private key in IndexedDB

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `record` | [`StoredPGPPrivateKey`](interfaces/StoredPGPPrivateKey.md) | The encrypted private key record to store |

#### Returns

`Promise`<`void`\>

___

### toCognitoAttributes

▸ **toCognitoAttributes**(`userDoc`): `Object`

Given a `UserDoc` from the maxcryptor, this returns an object
which you can provide to `Auth.updateUserAttributes()`. It is
an object of stringified Json.

Note: Only includes attributes that exist in userDoc. Missing attributes
are filtered out to avoid Cognito "Attribute value must not be null" errors.

#### Parameters

| Name | Type |
| :------ | :------ |
| `userDoc` | `UserDoc` |

#### Returns

`Object`

___

### uint8ArrayToBase64

▸ **uint8ArrayToBase64**(`bytes`): `string`

Convert Uint8Array to base64 string

#### Parameters

| Name | Type |
| :------ | :------ |
| `bytes` | `Uint8Array` |

#### Returns

`string`

___

### validateImportedKey

▸ **validateImportedKey**(`parsedKey`): [`KeyValidationResult`](interfaces/KeyValidationResult.md)

Validate an imported key

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `parsedKey` | [`ParsedPGPKey`](interfaces/ParsedPGPKey.md) | Parsed key to validate |

#### Returns

[`KeyValidationResult`](interfaces/KeyValidationResult.md)

Validation result with any warnings

___

### verifySignature

▸ **verifySignature**(`data`, `signature`, `publicKey`): `Promise`<`boolean`\>

Verify an RSA-PSS signature

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `data` | `Uint8Array` | Original data that was signed |
| `signature` | `Uint8Array` | Signature bytes to verify |
| `publicKey` | `CryptoKey` | CryptoKey configured for RSA-PSS verification |

#### Returns

`Promise`<`boolean`\>

True if signature is valid, false otherwise

___

### verifyTextSignature

▸ **verifyTextSignature**(`text`, `signatureBase64`, `publicKey`): `Promise`<`boolean`\>

Verify a base64-encoded signature for text

Convenience wrapper that decodes base64 signature and encodes text to UTF-8.

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `text` | `string` | Original text that was signed |
| `signatureBase64` | `string` | Base64-encoded signature to verify |
| `publicKey` | `CryptoKey` | CryptoKey configured for RSA-PSS verification |

#### Returns

`Promise`<`boolean`\>

True if signature is valid, false otherwise

___

### xorBytes

▸ **xorBytes**(`a`, `b`): `Uint8Array`

XOR two byte arrays of equal length

Used for combining password-derived key with LocalSecret in 2SKD.
This follows the 1Password approach of XOR combination.

**`Throws`**

Error if arrays are not the same length

#### Parameters

| Name | Type | Description |
| :------ | :------ | :------ |
| `a` | `Uint8Array` | First byte array |
| `b` | `Uint8Array` | Second byte array |

#### Returns

`Uint8Array`

XOR result
