14 KiB
@zk-email/circuits Package Overview
The circuits package exports the circom circuits needed for building on ZK Email.
All circuits in this package are libraries that can be imported to your circom project (i.e this package does not contain a main circuit).
Installation
yarn add @zk-email/circuits
EmailVerifier Circuit
EmailVerifier is the primary circuit exported from @zk-email/circuits which is used for proving the signature of the input email is valid.
Usage:
Import to your circuit file like below.
include "@zk-email/circuits/email-verifier.circom";
-
Parameters:
maxHeadersLength: Maximum length for the email header.maxBodyLength: Maximum length for the email body.n: Number of bits per chunk the RSA key is split into. Recommended to be 121.k: Number of chunks the RSA key is split into. Recommended to be 17.ignoreBodyHashCheck: Set 1 to skip body hash check in case data to prove/extract is only in the headers.
-
Input Signals:
emailHeader[maxHeadersLength]: Email headers that are signed (ones inDKIM-Signatureheader) as ASCII int[], padded as per SHA-256 block size.emailHeaderLength: Length of the email header including the SHA-256 padding.pubkey[k]: RSA public key split into k chunks of n bits each.signature[k]: RSA signature split into k chunks of n bits each.emailBody[maxBodyLength]: Email body after the precomputed SHA as ASCII int[], padded as per SHA-256 block size.emailBodyLength: Length of the email body including the SHA-256 padding.bodyHashIndex: Index of the body hashbhin theemailHeader.precomputedSHA[32]: Precomputed SHA-256 hash of the email body till the bodyHashIndex.
Output Signal
pubkeyHash: Poseidon hash of the pubkey - Poseidon(n/2)(n/2 chunks of pubkey with k*2 bits per chunk).
Libraries
The package also exports circuits for some popular cryptographic protocols.
They are used in EmailVerifier circuit for signature verification, but can also be used independently in other ZK projects (even when not using ZK Email).
@zk-email/circuits/lib/rsa.circom
RSAVerifier65537: Verifies RSA signatures with exponent 65537.
- Source
- Parameters
n: Number of bits per chunk the modulus is split into. Recommended to be 121.k: Number of chunks the modulus is split into. Recommended to be 17.
- Inputs:
message[k]: The message that was signed.signature[k]: The signature to verify.modulus[k]: The modulus of the RSA key (pubkey).
sha.circom
Sha256Bytes
Sha256Bytes: Utilized for SHA-256 hashing of byte arrays. This is suitable for processing various types of data, such as email headers and bodies, within the constraints of the circuit.
- Inputs:
in_padded: The byte array to be hashed, padded according to SHA-256 requirements.
in_len_padded_bytes: The byte length of the padded input.
- Output:
- A 256-bit array representing the SHA-256 hash of the input.
- Usage:
- To hash data using
Sha256Bytes, include this template in your circuit and provide the necessary inputs to receive the SHA-256 hash output.
Sha256BytesPartial: Facilitates SHA-256 hashing with an optimization for known partial pre-hash states.
- Inputs:
in_padded: The byte array for hashing, with appropriate padding.
in_len_padded_bytes: The byte length of the padded input.
pre_hash: A 32-byte array representing the partial pre-hash state.
- Output:
- A 256-bit array representing the SHA-256 hash of the input, taking into account the pre-hash state.
- Usage:
- For optimized SHA-256 hashing with a known pre-hash state, use
Sha256BytesPartial by specifying the inputs, including the pre-hash state.
base64.circom
This component decodes base64 encoded data within arithmetic circuits, focusing on the conversion of base64 encoded strings into binary data.
Base64Decode: Decodes a base64 encoded string into binary data.
-
Inputs:
in: The base64 encoded string to decode.
N: The expected length of the output binary data.
-
Outputs:
out: The decoded binary data.
-
Usage:
- To decode base64 encoded data, include the
Base64Decode template in your circuit and provide the encoded string as input. The template will output the decoded binary data.
Utilities
These utility templates in circom are used to support the creation of zk proofs, extending beyond the confines of our predefined code.
array.circom
ItemAtIndex: This template selects an item at a given index from the input array. It is based on the QuinSelector from MACI.
- Parameters:
maxArrayLen: The number of elements in the array.
- Inputs:
in: The input array.
index: The index of the element to select.
- Output:
out: The selected element.
- Usage:
- To select an item from an array at a specific index, use the
ItemAtIndex template by specifying the array and the index.
CalculateTotal: This template calculates the sum of an array.
- Inputs:
nums: The input array.
- Output:
sum: The sum of the input array.
- Usage:
- To calculate the total sum of an array, include the
CalculateTotal template in your circuit and provide the array as input.
SelectSubArray: Extracts a segment from an array using a starting index (startIndex) and segment length (length), zeroing elements outside this range.
- Parameters:
maxArrayLen: The upper limit on the byte count within the input array.
maxSubArrayLen: The maximum count of integers allowed within the resultant sub-array.
- Inputs:
in: The byte array from which a segment is to be extracted.
startIndex: The array index at which the desired segment begins.
length: The extent of the segment, defined by the number of elements it encompasses.
- Output:
out: A maxSubArrayLen-sized array, populated starting from startIndex for the defined length, with subsequent elements reset to zero.
- Usage:
- To isolate a segment from an array, the
SelectSubArray template should be employed, specifying the original array, the commencement index, and the segment length.
VarShiftLeft:This template shifts an input array by shift indices to the left. The output array length can be reduced by setting maxOutArrayLen.
- Parameters:
maxArrayLen: The maximum length of the input array.
maxOutArrayLen: The maximum length of the output array.
- Inputs:
in: The input array.
shift: The number of indices to shift the array to the left.
- Output:
out: Shifted subarray.
- Usage:
- To shift an array to the left by a specific number of indices, include the
VarShiftLeft template in your circuit and specify the array and shift amount.
AssertZeroPadding: This template asserts that the input array is zero-padded from the given startIndex.
- Parameters:
maxArrayLen: The maximum number of elements in the input array.
- Inputs:
in: The input array.
startIndex: The index from which the array should be zero-padded.
- Usage:
- To ensure an array is zero-padded from a specific index, use the
AssertZeroPadding template by specifying the array and start index.
bytes.circom
These templates are for converting byte arrays into integer arrays, considering specified packing sizes, and for packing byte arrays to numbers that fit in a field.
PackBytes: Packs an array of bytes to numbers that fit in the field.
- Inputs:
in: The input byte array.
maxBytes: The maximum number of bytes in the input array.
- Outputs:
out: The output integer array after packing.
- Usage:
- To pack byte data to integers, include the
PackBytes template in your circuit and provide the byte array as input. The template will output the packed integer array.
PackByteSubArray: Selects a sub-array from the input array and packs it to numbers that fit in the field.
- Inputs:
in: The input byte array.
startIndex: The start index of the sub-array.
length: The length of the sub-array.
maxArrayLen: The maximum number of elements in the input array.
maxSubArrayLen: The maximum number of elements in the sub-array.
- Outputs:
out: The output integer array after packing the sub-array.
- Usage:
- To pack a specific sub-array of byte data to integers, use the
PackByteSubArray template by specifying the inputs, including the start index and length of the sub-array.
DigitBytesToInt: Converts a byte array representing digits to an integer.
- Inputs:
in: The input byte array - big-endian digit string of out.
n: The number of bytes in the input array.
- Outputs:
out: The output integer after conversion.
- Usage:
- To convert a byte array of digit characters into an integer, include the
DigitBytesToInt template in your circuit and provide the byte array as input. The template will output the corresponding integer.
constants.circom
This file defines a set of constants used across various circom circuits for standardizing sizes and lengths of different data types.
- Constants:
EMAIL_ADDR_MAX_BYTES(): Returns the maximum byte size for an email, defined as 256.
DOMAIN_MAX_BYTES(): Returns the maximum byte size for a domain, defined as 255.
MAX_BYTES_IN_FIELD(): Returns the maximum number of bytes that can fit in a field, defined as 31.
functions.circom
This file contains utility functions that are used across various circom circuits for performing common mathematical and logical operations.
log2Ceil: Calculates the ceiling of the base 2 logarithm of a given number.
- Inputs:
a: The input number for which the base 2 logarithm ceiling is to be calculated.
- Outputs:
- Returns the smallest integer greater than or equal to the base 2 logarithm of the input number.
- Usage:
- To calculate the ceiling of the base 2 logarithm of a number, include the
log2Ceil function in your circuit and provide the number as input. The function will return the calculated value.
hash.circom
PoseidonLarge: Circuit to calculate Poseidon hash of inputs more than 16.
- Inputs:
in[chunkSize]: The input array of chunkSize elements.
bytesPerChunk: Number of bits in each chunk.
chunkSize: Number of chunks in input.
- Outputs:
out: Poseidon hash of input where consecutive elements are merged.
- Usage:
- To calculate a Poseidon hash for large inputs, include the
PoseidonLarge template in your circuit and provide the necessary inputs. The template will output the Poseidon hash of the input.
regex.circom
This file contains templates for performing operations related to regular expressions on byte arrays. These templates allow for selecting and packing parts of byte arrays that match specific patterns defined by regular expressions.
SelectRegexReveal: Selects the reveal part of a byte array that matches a regular expression.
- Inputs:
in: The input byte array.
startIndex: The index of the start of the reveal part in the input array.
maxArrayLen: The maximum length of the input array.
maxRevealLen: The maximum length of the reveal part.
- Outputs:
out: The revealed data array that matches the regular expression.
- Usage:
- To extract a specific part of a byte array that matches a regular expression, use the
SelectRegexReveal template by specifying the inputs, including the start index of the reveal part.
PackRegexReveal: Packs the reveal data from a regex match into an integer array.
- Inputs:
in: The input byte array.
startIndex: The index of the start of the reveal part in the input array.
maxArrayLen: The maximum length of the input array.
maxRevealLen: The maximum length of the reveal part.
- Outputs:
out: The packed integer array after processing the reveal data.
- Usage:
- To pack the reveal data from a regular expression match into integers, use the
PackRegexReveal template by specifying the inputs, including the start index of the reveal part.
Sha256Bytes: Utilized for SHA-256 hashing of byte arrays. This is suitable for processing various types of data, such as email headers and bodies, within the constraints of the circuit.in_padded: The byte array to be hashed, padded according to SHA-256 requirements.in_len_padded_bytes: The byte length of the padded input.
- A 256-bit array representing the SHA-256 hash of the input.
- To hash data using
Sha256Bytes, include this template in your circuit and provide the necessary inputs to receive the SHA-256 hash output.
Sha256BytesPartial: Facilitates SHA-256 hashing with an optimization for known partial pre-hash states.in_padded: The byte array for hashing, with appropriate padding.in_len_padded_bytes: The byte length of the padded input.pre_hash: A 32-byte array representing the partial pre-hash state.
- A 256-bit array representing the SHA-256 hash of the input, taking into account the pre-hash state.
- For optimized SHA-256 hashing with a known pre-hash state, use
Sha256BytesPartialby specifying the inputs, including the pre-hash state.
Base64Decode: Decodes a base64 encoded string into binary data.Inputs:
in: The base64 encoded string to decode.N: The expected length of the output binary data.
Outputs:
out: The decoded binary data.
Usage:
- To decode base64 encoded data, include the
Base64Decodetemplate in your circuit and provide the encoded string as input. The template will output the decoded binary data.
ItemAtIndex: This template selects an item at a given index from the input array. It is based on the QuinSelector from MACI.maxArrayLen: The number of elements in the array.
in: The input array.index: The index of the element to select.
out: The selected element.
- To select an item from an array at a specific index, use the
ItemAtIndextemplate by specifying the array and the index.
CalculateTotal: This template calculates the sum of an array.nums: The input array.
sum: The sum of the input array.
- To calculate the total sum of an array, include the
CalculateTotaltemplate in your circuit and provide the array as input.
SelectSubArray: Extracts a segment from an array using a starting index (startIndex) and segment length (length), zeroing elements outside this range.maxArrayLen: The upper limit on the byte count within the input array.maxSubArrayLen: The maximum count of integers allowed within the resultant sub-array.
in: The byte array from which a segment is to be extracted.startIndex: The array index at which the desired segment begins.length: The extent of the segment, defined by the number of elements it encompasses.
out: AmaxSubArrayLen-sized array, populated starting fromstartIndexfor the definedlength, with subsequent elements reset to zero.
- To isolate a segment from an array, the
SelectSubArraytemplate should be employed, specifying the original array, the commencement index, and the segment length.
VarShiftLeft:This template shifts an input array by shift indices to the left. The output array length can be reduced by setting maxOutArrayLen.maxArrayLen: The maximum length of the input array.maxOutArrayLen: The maximum length of the output array.
in: The input array.shift: The number of indices to shift the array to the left.
out: Shifted subarray.
- To shift an array to the left by a specific number of indices, include the
VarShiftLefttemplate in your circuit and specify the array and shift amount.
AssertZeroPadding: This template asserts that the input array is zero-padded from the given startIndex.maxArrayLen: The maximum number of elements in the input array.
in: The input array.startIndex: The index from which the array should be zero-padded.
- To ensure an array is zero-padded from a specific index, use the
AssertZeroPaddingtemplate by specifying the array and start index.
PackBytes: Packs an array of bytes to numbers that fit in the field.in: The input byte array.maxBytes: The maximum number of bytes in the input array.
out: The output integer array after packing.
- To pack byte data to integers, include the
PackBytestemplate in your circuit and provide the byte array as input. The template will output the packed integer array.
PackByteSubArray: Selects a sub-array from the input array and packs it to numbers that fit in the field.in: The input byte array.startIndex: The start index of the sub-array.length: The length of the sub-array.maxArrayLen: The maximum number of elements in the input array.maxSubArrayLen: The maximum number of elements in the sub-array.
out: The output integer array after packing the sub-array.
- To pack a specific sub-array of byte data to integers, use the
PackByteSubArraytemplate by specifying the inputs, including the start index and length of the sub-array.
DigitBytesToInt: Converts a byte array representing digits to an integer.in: The input byte array - big-endian digit string ofout.n: The number of bytes in the input array.
out: The output integer after conversion.
- To convert a byte array of digit characters into an integer, include the
DigitBytesToInttemplate in your circuit and provide the byte array as input. The template will output the corresponding integer.
EMAIL_ADDR_MAX_BYTES(): Returns the maximum byte size for an email, defined as 256.DOMAIN_MAX_BYTES(): Returns the maximum byte size for a domain, defined as 255.MAX_BYTES_IN_FIELD(): Returns the maximum number of bytes that can fit in a field, defined as 31.
log2Ceil: Calculates the ceiling of the base 2 logarithm of a given number.
- Inputs:
a: The input number for which the base 2 logarithm ceiling is to be calculated.
- Outputs:
- Returns the smallest integer greater than or equal to the base 2 logarithm of the input number.
- Usage:
- To calculate the ceiling of the base 2 logarithm of a number, include the
log2Ceilfunction in your circuit and provide the number as input. The function will return the calculated value.
- To calculate the ceiling of the base 2 logarithm of a number, include the
PoseidonLarge: Circuit to calculate Poseidon hash of inputs more than 16.in[chunkSize]: The input array of chunkSize elements.bytesPerChunk: Number of bits in each chunk.chunkSize: Number of chunks in input.
out: Poseidon hash of input where consecutive elements are merged.
- To calculate a Poseidon hash for large inputs, include the
PoseidonLargetemplate in your circuit and provide the necessary inputs. The template will output the Poseidon hash of the input.
SelectRegexReveal: Selects the reveal part of a byte array that matches a regular expression.in: The input byte array.startIndex: The index of the start of the reveal part in the input array.maxArrayLen: The maximum length of the input array.maxRevealLen: The maximum length of the reveal part.
out: The revealed data array that matches the regular expression.
- To extract a specific part of a byte array that matches a regular expression, use the
SelectRegexRevealtemplate by specifying the inputs, including the start index of the reveal part.
PackRegexReveal: Packs the reveal data from a regex match into an integer array.in: The input byte array.startIndex: The index of the start of the reveal part in the input array.maxArrayLen: The maximum length of the input array.maxRevealLen: The maximum length of the reveal part.
out: The packed integer array after processing the reveal data.
- To pack the reveal data from a regular expression match into integers, use the
PackRegexRevealtemplate by specifying the inputs, including the start index of the reveal part.