# Crypto

This module gives access to various cryptograhic functions provided by the Web Crypto API.

In addition to supporting generating random values and UUIDs, this module supports the following algorithms and operations:

- RSA-OAEP - Encryption and decryption
- AES-CTR - Encryption and decryption
- AES-CBC - Encryption and decryption
- AES-GCM - Encryption and decryption
- RSA-SSAPKCS1v1.5 - Signing and verifying
- RSA-PSS - Signing and verifying
- ECDSA - Signing and verifying
- HMAC - Signing and verifying
- SHA - Digest

All of the above algorithms also have appropriate key generation, import, and export functions.

## Secure Context

Many functions in this module must be run in a secure context to operate safely and correctly. Before you use any functions, it's likely that you'll need to obtain and store the SecureContext value in your model.

Represents the platform being considered secure. This type can be generated using the
`getSecureContext`

function and is required for some functions to be run in this package.

A `Task`

that succeeds with `SecureContext`

if the code is being run in a
secure context. If this `Task`

fails, most of the functions within this module
will not be able to run.

While running this function on the `node`

platform, it should succeed unless you
are running a version of `node`

that does not support the Web Crypto APIs.

While running this function on the `browser`

platform, it will succeed if the
application being run is considered as being in a secure context.

## Generate Random Values

Generate random values of 8, 16, or 32 bits long (signed and unsigned).

All functions for generating random values take an `Int`

as the single parameter.
This value is clamped to a minimum of `0`

and a maximum of however many values can
be generated.

The maximum number of values that can be generated depends on the amount of bytes
the values you're generating are. 65536 is the maximum number of bytes that can be
generated. For example, when using `getRandomInt16Values`

, each value is 16 bits
(or 2 bytes), so the maximum number of values that `getRandomInt16Values`

can generate
is 32768 values.

Get some `Bytes`

of random, signed, 8-bit values equal to the length of the passed `Int`

with a maximum of 65536 values.

Get some `Bytes`

of random, unsigned, 8-bit values equal to the length of the passed `Int`

with a maximum of 65536 values.

Get some `Bytes`

of random, signed, 16-bit values equal to the length of the passed `Int`

.
with a maximum of 32768 values.

Get some `Bytes`

of random, unsigned, 16-bit values equal to the length of the passed `Int`

.
with a maximum of 32768 values.

Get some `Bytes`

of random, signed, 32-bit values equal to the length of the passed `Int`

with a maximum of 16384 values.

Get some `Bytes`

of random, unsigned, 32-bit values equal to the length of the passed `Int`

with a maximum of 16384 values.

## Generate Random UUIDs

Generate a random UUID using the UUID v4 algorithm.

## Encryption & Decryption

Encrypt and decrypt values. Each operation requires a specific key for the algorithm being used. You can learn more about key generation in the "Key Generation" section of this module.

### Encrypt & decrypt with the RSA-OAEP algorithm

Encrypt and decrypt `Bytes`

with the RSA-OAEP (Rivest-Shamir-Adleman Optimal Asymmetric
Encryption Padding) algorithm. These functions require an RSA-OAEP key pair. You can
generate one with the `generateRsaOaepKeyPair`

function.

The parameters needed to encrypt or decrypt with the RSA-OAEP algorithm. There's only
one parameter: a `label`

consisting of some `Bytes`

. The label is completely optional and
passing `Nothing`

will not make the operation less secure.

Errors that can happen when encrypting using the `encryptWithRsaOaep`

function.

This error should only appear if there are problems in kernel code. If you run into it, please file a ticket!

Encrypt some `Bytes`

with a `PublicKey RsaOaepKey`

. You can generate the apporpriate
key with the `generateRsaOaepKeyPair`

function.

Errors that can happen when decrypting `Bytes`

using the `decryptWithRsaOaep`

function.
There are two cases where the function can fail:

- The
`label`

used to encrypt the data does not match the label used when decrypting the data - The decryption algorithm fails due to the passed
`Bytes`

not being suitable for decryption (for whatever reason)

Decrypt some `Bytes`

with a `PrivateKey RsaOaepKey`

. You can generate the apporpriate key with the
`generateRsaOaepKeyPair`

function.

### Encrypt & decrypt with the AES-CTR algorithm

Encrypt and decrypt `Bytes`

with the AES-CTR (Advanced Encryption Standard - Counter Mode)
algorithm. These functions require an AES-CTR key. You can generate one with the
`generateAesCtrKey`

function.

Required paramaters to encrypt and decrypt values with the AES-CTR algorithm.

`counter`

must be exactly 16 bytes, or else encryption and decryption will fail.`length`

must be between 1 and 128. If provided an`Int`

that is below or above that range, it will be clamped to prevent the operation from failing.

Errors that can happen when encrypting using the `encryptWithAesCtr`

function. There are two cases where this function can fail:

- When the passed
`counter`

in`AesCtrParams`

is greater or less than than the required 16 bytes. This is captured by`AesCtrEncryptionErrorCounterTooLong`

. - Any unknown or unexpected errors are captured with
`AesCtrEncryptionError`

.

Encrypt some Bytes with a `Key AesCtrKey`

. You can generate the apporpriate key
with the `generateAesCtrKey`

function.

Errors that can happen when decrypting `Bytes`

using the `decryptWithAesCtr`

function.
There are a few cases where this function can fail:

- The passed
`Bytes`

are unable to be decrypted for whatever reason. This is captured by`AesCtrDecryptionError`

. - When the passed
`counter`

in`AesCtrParams`

is greater or less than than the required 16 bytes. This is captured by`AesCtrDecryptionErrorCounterTooLong`

- Any unknown or unexpected errors are captured by
`AesCtrDecryptionError`

.

Decrypt some Bytes with a `Key AesCtrKey`

. You can generate the apporpriate key
with the `generateAesCtrKey`

function.

### Encrypt & decrypt with the AES-CBC algorithm

Encrypt and decrypt `Bytes`

with the AES-CBC (Advanced Encryption Standard - Cipher Block
Chaining) algorithm. These functions require an AES-CBC key. You can generate one with the
`generateAesCbcKey`

function.

Required paramaters to encrypt and decrypt values with the AES-CBC algorithm.

`iv`

should be exactly 16 bytes. These bytes should be random, but do not need to be secret.

Errors that can happen when encrypting `Bytes`

using the `encryptWithAesCbc`

function. There are a few cases where this function can fail:

- The passed
`Bytes`

are unable to be decrypted for whatever reason. This is captured by`AesCbcDecryptionError`

. - When the passed
`iv`

in`AesCtrParams`

is greater or less than than the required 16 bytes. This is captured by`AesCbcEncryptionErrorIvTooLong`

- Any unknown or unexpected errors are captured by
`AesCbcDecryptionError`

.

Encrypt some Bytes with a `Key AesCbcKey`

. You can generate the apporpriate key
with the `generateAesCbcKey`

function.

Errors that can happen when decrypting `Bytes`

using the `decryptWithAesCbc`

function. There are a few cases where this function can fail:

- The passed
`Bytes`

are unable to be decrypted for whatever reason. This is captured by`AesCbcDecryptionError`

. - The passed
`iv`

does not match the`iv`

used when the data was encrypted. This is captured by`AesCbcDecryptionError`

. - When the passed
`iv`

in`AesCbcParams`

is greater or less than than the required 16 bytes. This is captured by`AesCtrDecryptionErrorIvTooLong`

- Any unknown or unexpected errors are captured by
`AesCtrDecryptionError`

.

Decrypt some `Bytes`

with a `Key AesCbcKey`

. You can generate the apporpriate key with the
`generateAesCbcKey`

function.

### Encrypt & decrypt with the AES-GCM algorithm

Encrypt and decrypt `Bytes`

with the AES-GCM (Advanced Encryption Standard - Galois/Counter Mode)
algorithm. These functions require an AES-GCM key. You can generate one with the
`generateAesGcmKey`

function.

Required paramaters to encrypt and decrypt values with the AES-GCM algorithm.

`iv`

needs to be be greater than 12 bytes, but less than 128 bytes. The recommended length is 96 bytes.`additionalData`

is completely optional data that is not encrypted, but will be a part of the completed, encrypted,`Bytes`

. If provided when encrypting data, the same value must be provided when decrypting it or else the operation will fail.`tagLength`

is optional and defaults to`AesTagLength128`

, which is recommended. You can find more information about this on the Web Crypto API docs.

The set of allowed tag lengths for the AES-GCM algorithm.

Errors that can happen when encrypting `Bytes`

using the `encryptWithAesGcm`

function. There are a few cases where this function can fail:

- When the passed
`iv`

in`AesGcmParams`

is longer or shorter than required. This is captured by`AesGcmEncryptionErrorInvalidIvByteLegth`

. - Any unknown or unexpected errors are captured with
`AesCtrEncryptionError`

.

Encrypt some `Bytes`

with a `Key AesGcmKey`

. You can generate the apporpriate
key with the `generateAesGcmKey`

function.

Errors that can happen when decrypting `Bytes`

using the `decryptWithAesGcm`

function. There are a few cases where this function can fail:

- The passed
`Bytes`

are unable to be decrypted for whatever reason. This is captured by`AesGcmDecryptionError`

. - When the passed
`iv`

in`AesGcmParams`

is longer or shorter than required. This is captured by`AesGcmDecryptionErrorInvalidIvByteLegth`

. - If the passed
`iv`

for encrypting the data does not match the`iv`

being used to decrypt the data. This is captured with`AesCtrDecryptionError`

. - Any unknown or unexpected errors are captured with
`AesCtrDecryptionError`

.

Decrypt some `Bytes`

with a `Key AesGcmKey`

. You can generate the apporpriate
key with the `generateAesGcmKey`

function.

## Signing & Verifying

Sign and verify values. Each operation requires a specific key for the algorithm being used. You can learn more about key generation in the "Key Generation" section of this module.

A handy alias for differentiating between artibrary `Bytes`

and the `Bytes`

of a generated
signature (using a signing function).

### Sign & verify with the RSASSA-PKCS1-v1_5 algorithm

Sign and verify some `Bytes`

with the RSASSA-PKCS1-v1_5 (Rivest, Shamir, and Adleman Signature Scheme
with Appendix ...) algorithm. These functions require an RSASSA-PKCS1-v1_5 key. You can generate one
with the `generateRsaSsaPkcs1V1_5KeyPair`

function.

Errors that can happen when signing using the
`signWithRsaSsaPkcs1V1_5`

function.

This error should only appear if there are problems in kernel code. If you run into it, please file a ticket!

Sign some `Bytes`

with the RSA-SSAPKCS1v1.5 algorithm. This produces a `Signature`

(which
is just some `Bytes`

). The `Signature`

can be used with the cooresponding verification function
to verify that the passed `Bytes`

were signed with the passed key.

Verify that some `Bytes`

were signed with the passed `Signature`

with the
RSA-SSAPKCS1v1.5 algorithm.

This function produces no values. Instead, the `Task`

succeeds if the passed
signature is valid and fails otherwise.

### Sign & verify with the RSA-PSS algorithm

Sign and verify some `Bytes`

with the RSA-PSS (Rivest, Shamir, and Adleman - Probabilistic Signature
Scheme) algorithm. These functions require an RSA-PSS key. You can generate one with the
`generateRsaPssKeyPair`

function.

The parameters needed to sign or verify with the RSA-PSS algorithm.

Errors that can happen when signing using the `signWithRsaPss`

function. There are
a few cases where this function can fail:

- If the passed
`salt`

as part of the`RsaPssParams`

is not equal to or less than the amount of bytes of the`DigestAlgorithm`

that was used to generate the key. For example, if the`RsaPssKey`

was generated with SHA-256, the maximum number for the`salt`

value must be 32 or less. This is captured by`RsaPssSigningErrorInvalidSalt`

. - Any unknown or unexpected errors are captured with
`RsaPssSigningError`

.

Sign some `Bytes`

with the RSA-PSS algorithm. This produces a `Signature`

(which
is just some `Bytes`

). The `Signature`

can be used with the cooresponding verification function
to verify that the passed `Bytes`

were signed with the passed key.

Verify that some `Bytes`

were signed with the passed `Signature`

with the
RSA-PSS algorithm.

This function produces no values. Instead, the `Task`

succeeds if the passed
signature is valid and fails otherwise.

### Sign & verify with the ECDSA algorithm

Sign and verify some `Bytes`

with the ECDSA (Elliptic Curve Digital Signature Algorithm) algorithm.
These functions require an RSA-PSS key. You can generate one with the
`generateEcdsaKeyPair`

function.

Sign some `Bytes`

with the ECDSA algorithm. This produces a `Signature`

(which
is just some `Bytes`

). The `Signature`

can be used with the cooresponding verification function
to verify that the passed `Bytes`

were signed with the passed key.

The returned `Task`

should not fail. If it does, please file a ticket!

Verify that some `Bytes`

were signed with the passed `Signature`

with the
ECDSA algorithm.

This function produces no values. Instead, the `Task`

succeeds if the passed
signature is valid and fails otherwise.

### Sign & verify with the HMAC algorithm

Sign and verify some `Bytes`

with the HMAC (Hash-Based Message Authentication Code) algorithm.
These functions require an RSA-PSS key. You can generate one with the
`generateEcdsaKeyPair`

function.

Sign some `Bytes`

with the HMAC algorithm. This produces a `Signature`

(which
is just some `Bytes`

). The `Signature`

can be used with the cooresponding verification function
to verify that the passed `Bytes`

were signed with the passed key.

The returned `Task`

should not fail. If it does, please file a ticket!

Verify that some `Bytes`

were signed with the passed `Signature`

with the
HMAC algorithm.

`Task`

succeeds if the passed
signature is valid and fails otherwise.

## Digest

Supported algorithms suitable for digesting data.

Note: The algorithm `SHA1`

is supported by the WebCrypto API, but not available
in this package due to known security vunerabilities.

Take some `Bytes`

and create a hash from them using the passed `DigestAlgorithm`

.
This operation should always succeed.

## Generate Keys

Generate, import, and export keys for completing cryptographic operations.

A generated key.

A public key that is used for encrypting and verifying values. This key type, as the name suggests, can be exposed publicly and is safe to transport across the network.

A private key that is used for decrypting and signing values. This key should be protected and not revealed to any system outside of your application.

A set of public and private keys created by some key generation algorithms.

Denotes if a key can be exported using the `exportKey`

or `exportKeyPair`

functions. If a key is not marked as exportable when it is created or imported,
any attempts to export the key will fail.

### Generate RSA Keys

Generate keys to use with RSA (Rivest-Shamir-Adleman) algorithm.

Parameters required to generate a key for use with the RSA algorithm.

`modulusLength`

is clamped be at least 2048 and no greater than 4096. If the`Int`

used is outside of that range, it will be corrected. It also needs to be divisible by 8.`hash`

is the`DigestAlgorithm`

that's used for key generation`extractable`

denotes that if this key is extractable or not. For more information, see the`Extractable`

type documentation.

A missing part of these parameters is the public exponent. Generated keys will always
have a `[ 1, 0, 1 ]`

or `65537`

public exponent. This is a recommended value and a value
that works across the `browser`

and `node`

platforms. If you have need for other public
exponents, please file a ticket!

Errors that can happen when generating a key for use with the RSA algorithm. There is a single case where this function can fail at runtime:

- When the passed
`modulusLength`

is not divisible by 8, as is required by the algorithm. This is captured by`ModulusLengthNotDivisibleByEight`

.

Generate a new key pair using the RSA-OAEP algorithm.

Produces a `KeyPair`

that can be used to encrypt data with `encryptWithRsaOaep`

and decrypt data with `decryptWithRsaOaep`

.

Generate a new key using the RSA-PSS algorithm.

Produces a `KeyPair`

that can be used to sign data with `signWithRsaPss`

and verify data with `verifyWithRsaPss`

.

Generate a new key using the RSASSA-PKCS1-v1_5 algorithm.

Produces a `KeyPair`

that can be used to sign data with
`signWithRsaSsaPkcs1V1_5`

and verify data with
`verifyWithRsaSsaPkcs1V1_5`

.

### Generate AES Keys

Generate keys to use with AES (Advanced Encryption Standard) algorithm.

Parameters required to generates an AES key.

`length`

is the length, in bits, of the generated key. It must be one of the`AesLength`

type.`extractable`

denotes that if this key is extractable or not. For more information, see the`Extractable`

type documentation.

The length of bits of the key that is being generated using the AES algorithm. These are the only values that can be chosen.

The Web Crypto API supports a length of 192, but some browsers do not implement
this. To keep compatability across the `browser`

platform, the option is not provided.

Generate a new key using the AES-CTR algorithm.

Produces a `Key`

that can be used to encrypt data with `encryptWithAesCtr`

and decrypt data with `decryptWithAesCtr`

.

Generate a new key using the AES-CBC algorithm.

Produces a `Key`

that can be used to encrypt data with `encryptWithAesCbc`

and decrypt data with `decryptWithAesCbc`

.

Generate a new key using the AES-GCM algorithm.

Produces a `Key`

that can be used to encrypt data with `encryptWithAesGcm`

and decrypt data with `decryptWithAesGcm`

.

### Generate EC Keys

Generate keys to use with EC (Elliptic Curve) algorithm.

Parameters required to generates an AES key.

`namedCurve`

is the curve used to generate the key. It must be one of the`EcNamedCurve`

variant.`extractable`

denotes that if this key is extractable or not. For more information, see the`Extractable`

type documentation.

The name of the elliptic curve to use for the generated key.

Generate a new key using the ECDSA algorithm.

Produces a `KeyPair`

that can be used to sign data with `signWithEcdsa`

and verify data with `verifyWithEcdsa`

.

### Generate HMAC Keys

Generate keys to use with HMAC (Hash-Based Message Authentication Code) algorithm.

Parameters required to generate a key for use with the HMAC algorithm.

`length`

is the length of the resulting key in bits. If`Nothing`

, the key will be equal in bits to the passed`DigestAlgorithm`

. It's recommended to pass`Nothing`

and let the length of the key be equal to the hash function (`DigestAlgorithm`

). If passed, the`length`

is clamped be at least 8 and no greater than 2048. If the`Int`

used is outside of that range, it will be corrected.`hash`

is the`DigestAlgorithm`

that's used for key generation`extractable`

denotes that if this key is extractable or not. For more information, see the`Extractable`

type documentation.

Errors that can happen when generating a key for use with the RSA algorithm.

Errors that can happen when enerating a key for use with the HMAC algorithm. There's a single case where this function can fail:

- When the passed
`modulusLength`

is not divisible by 8, as is required by the algorithm. This is captured by`HmacLengthNotDivisibleByEight`

.

Generate a new key using the HMAC algorithm.

Produces a `Key`

that can be used to sign data with `signWithHmac`

and verify data with `verifyWithHmac`

.

## Export Keys

Export keys in various formats. Available formats depend on the key being exported. For more information on exporting keys, check out the MDN web docs for the Web Crypto API.

Errors that can arise when exporting keys.

`KeyNotExportable`

happens when trying to export a key that was not made`Extractable`

during creation or import.

### Export RSA Keys

### Export AES Keys

### Export EC Keys

### Export HMAC Keys

## Import Keys

Import keys generated in this module or generated elsewhere. For more information on exporting keys, check out the MDN web docs for the Web Crypto API.

### Import RSA Keys

Errors that can happen when importing a key using an RSA algorithm. There are a few possible reasons this error happens:

- The passed key value (either
`Json.Encode.Value`

or`Bytes`

) is not a valid key and cannot be imported. - The
`hash`

passed to the function does not match the`hash`

of the imported key. This only happens when importing a JSON Web Key. It is recommended to*always*match the hash of the imported key or you will get different results when using the imported key, even when not importing in the JSON Web Key format.

### Import AES Keys

Errors that can happen when importing a key using an AES algorithm. There's only one known instance where this error can appear:

- The passed key value (either
`Json.Encode.Value`

or`Bytes`

) is not a valid key and cannot be imported.

### Import EC Keys

Errors that can happen when importing a key using an EC algorithm. There are two possible reasons this error happens:

- The passed key value (either
`Json.Encode.Value`

or`Bytes`

) is not a valid key and cannot be imported. - The
`EcNamedCurve`

passed to the function does not match the`EcNamedCurve`

of the imported key.

### Import HMAC Keys

Errors that can happen when importing a key using an HMAC algorithm. There are three known reasons an errors can happen when importing HMAC keys:

- The passed key
`Bytes`

value (either`Json.Encode.Value`

or`Bytes`

) is not a valid key and cannot be imported. - The
`length`

passed to the function is not correct for the imported key. - The
`hash`

passed to the function does not match the`hash`

of the imported key. This only happens when importing a JSON Web Key. It is recommended to*always*match the hash of the imported key or you will get different results when using the imported key for cryptographic functions.