# zk-email/helpers

The @zk-email/helpers package provides utility functions for email verification and cryptographic operations. It includes functions for handling RSA signatures, public keys, email bodies, and hashes.

### Installation

#### input-generators.ts

The `input-generators.ts`

file provides functions for generating inputs to the EmailVerifier circuit from raw email content or DKIM verification results. It includes utilities for padding, hashing, and preparing data.

**How to Import**:

**Inputs**:

For every email, the following inputs are mandatory for the EmailVerifier circuit:

`emailHeader`

: An array of strings representing the email header.`emailHeaderLength`

: A string representing the length of the email header.`pubkey`

: An array of strings representing the public key used for verification in an email.`signature`

: An array of strings representing the RSA-signature of an email.

Additionally, the `InputGenerationArgs`

include optional parameters that can be adjusted based on the verification requirements:

`ignoreBodyHashCheck`

: A boolean indicating whether to skip the email body contents.`shaPrecomputeSelector`

: A string used to select parts of the email body for SHA precomputation.`maxHeadersLength`

: The maximum length of the email header, including padding.`maxBodyLength`

: The maximum length of the email body after SHA precomputation, including padding.

If the `ignoreBodyHashCheck`

parameter is set to `false`

, additional inputs related to the email body are required for a more thorough verification process. These include:

`bodyHashIndex`

: a string representing the index of the bodyHash.`emailBody`

: An array of strings representing the email body.`emailBodyLength`

: A string representing the length of the email body.`precomputedSHA`

: An array of strings representing the precomputed SHA values.

**Functions**:

**generateEmailVerifierInputs**: Asynchronously generates circuit inputs for the EmailVerifier circuit from raw email content. It takes the full email content as a buffer or string and optional arguments to control the input generation, including`InputGenerationArgs`

.**generateEmailVerifierInputsFromDKIMResult**: Generates circuit inputs for the EmailVerifier circuit from a DKIMVerification result. It processes the DKIM verification result and optional arguments, including`InputGenerationArgs`

, to produce the necessary inputs for the EmailVerifier circuit.

The `input-generators.ts`

file imports other helper functions from our helpers package. It imports from `binary-format.ts`

, `constants.ts`

, `dkim/index.ts`

, and `sha-utils`

.

#### dkim/index.ts

The `dkim/index.ts`

file contains utilities for verifying DKIM signatures of emails. It uses the `node-forge`

library and includes custom sanitization logic `dkim/sanitizers.ts`

to improve the chances of successful DKIM verification.

**Key Components**:

**DKIMVerificationResult**: An interface that outlines the structure of the DKIM verification result, including the public key, signature, email headers, body, and other relevant information.**verifyDKIMSignature**: A function that takes an email (as a string or buffer), an optional domain, and a flag to enable sanitization. It attempts to verify the DKIM signature of the email, applying sanitization if necessary and enabled. The function returns a promise that resolves to a`DKIMVerificationResult`

.**tryVerifyDKIM**: An internal function used by`verifyDKIMSignature`

to perform the actual DKIM verification. It utilizes the`DkimVerifier`

class from the modified`./mailauth`

folder to process the email and extract DKIM verification results.

**Usage**:

To verify the DKIM signature of an email, import and call the `verifyDKIMSignature`

function with the email content. Optionally, specify the domain to verify against and whether to enable sanitization. The function returns a promise with the verification result.

#### binary-format.ts

The `binary-format.ts`

file provides functions for converting between strings, byte arrays, and other binary formats.This is particularly useful for handling data encoding and decoding within an application.

**stringToBytes**: Converts a string into its byte representation.**bytesToString**: Converts a byte array back into a string. Useful for decoding data received in binary format.**bufferToUint8Array**: Converts a Node.js Buffer into a Uint8Array.**bufferToHex**: Converts a Buffer to a hexadecimal string. This function is often used for displaying binary data in a readable format.**Uint8ArrayToCharArray**: Converts a Uint8Array to an array of character strings. This is used in the`input-generators.ts`

file.**Uint8ArrayToString**: Asynchronously converts a Uint8Array to a string, with each byte represented as a separate character in the string.**Uint8ArrayToHex**: Asynchronously converts a Uint8Array to a hexadecimal string. This is useful for encoding binary data as hex, a common format for displaying and transmitting binary data.**bufferToString**: Converts a Buffer directly to a string using UTF-8 encoding. This function simplifies the process of converting buffer data to a readable format.**bytesToBigInt**: Converts a byte array to a BigInt. This is helpful for cryptographic calculations that operate on large numbers.**bigIntToChunkedBytes**: Converts a BigInt to an array of byte strings, chunked according to specified sizes. This function is useful for preparing BigInt values for operations that require fixed-size byte arrays.**toCircomBigIntBytes**: Converts a BigInt to an array of bytes formatted for use with Circom. This is particularly useful when preparing data for zero-knowledge proofs in Circom and is used in the`input-generators.ts`

file.**toHex**: Converts a Uint8Array to a hexadecimal string efficiently. Useful to encode binary data as hex.**fromHex**: Converts a hexadecimal string to a Uint8Array. This function is the inverse of`toHex`

and is used for decoding hex-encoded data back into binary format.**int64toBytes**: Converts a 64-bit number to a Uint8Array. Note: Effectively handles 32-bit integers, placing them in the lower 4 bytes of the 8-byte array due to JavaScript's limitations.**int8toBytes**: Converts an 8-bit number (or a number that can fit within 8 bits) into a Uint8Array containing a single byte.**bitsToUint8**: Converts an array of bit strings (e.g., ["1", "0", "1"]) into a Uint8Array where each bit string is parsed into its corresponding byte value.**uint8ToBits**: Converts a Uint8Array into a string representation of its binary form. Each byte is represented as 8 bits in the resulting string.**mergeUInt8Arrays**: Merges two Uint8Array instances into a single Uint8Array.**assert**: Throws an error if the provided condition is false. This utility function is used to enforce certain conditions or invariants within the application.**packedNBytesToString**: Converts an array of bigint values, each representing`n`

bytes, back into a string.**packBytesIntoNBytes**: Packs a Uint8Array or string into an array of bigint values, with each bigint representing`n`

bytes of the input.

#### chunked-zkey.ts

The `chunked-zkey.ts`

file provides functions for handling `.zkey`

files, which are crucial for working with zk-SNARKs. These functions include downloading, storing, and uncompressing .zkey files, as well as generating and verifying proofs.

**uncompressGz**: Uncompresses a single`.gz`

file and returns the contents as an`ArrayBuffer`

.**downloadFromFilename**: Downloads a compressed file from a remote server, stores it with`localforage`

either as compressed or uncompressed, based on the specified parameter.**downloadProofFiles**: Downloads all necessary proof files for a given circuit name from a base URL, handling both compressed and uncompressed formats.**generateProof**: Generates a cryptographic proof for a given input using the`snarkjs`

library.**verifyProof**: Verifies a cryptographic proof against a set of public signals and a verification key.**buildInput**: Builds the input for a cryptographic proof from a public key, message hash, and signature, converting each component into the required format.

#### constants.ts

This file defines several constants, including `MAX_HEADER_PADDED_BYTES`

and `MAX_BODY_PADDED_BYTES`

, which are important for generating circuit inputs within `input-generators.ts`

. The maximum header size remains relatively constant, whereas the body size can vary significantly.

For a list of all constants, visit: constants.ts

#### sha-utils.ts

This file contains utility functions for SHA hash operations and manipulation of Uint8Array instances.

**findIndexInUint8Array**: Searches for a Uint8Array within another Uint8Array and returns the index of the first occurrence.**padUint8ArrayWithZeros**: Pads a Uint8Array with zeros until it reaches a specified length.**generatePartialSHA**: Generates a partial SHA hash of a Uint8Array up to a specified index, optionally splitting the array based on a selector string and ensuring the remaining array does not exceed a maximum length.**shaHash**: Computes the SHA-256 hash of a Uint8Array.**partialSha**: Computes a partial SHA-256 hash of a Uint8Array, allowing for the hash state to be cached and reused.**sha256Pad**: Pads a Uint8Array according to SHA-256 padding rules, appending a bit length and ensuring the total length is a multiple of 512 bits, suitable for SHA-256 processing.

Last updated