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.
yarn add @zk-email/helpers
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:
import { generateEmailVerifierInputs } from "@zk-email/helpers"
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
.
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 theDkimVerifier
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.
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.
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 anArrayBuffer
. -
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.
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
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.