We provide one main circuit as follows.
A circuit to verify that a message in the subject is authorized by a user of an account salt, derived from an email address in the From field and a random field value called account code.
It takes as input the following data:
- a padded email header
padded_header
. - the bytes of the padded email header
padded_header_len
. - an RSA public key
public_key
. - an RSA signature
signature
. - the sender's account code
account_code
. - a starting position of the From field in the email header
from_addr_idx
. - a starting position of the Subject field in the email header
subject_idx
. - a starting position of the email domain in the email address of the From field
domain_idx
. - a starting position of the timestamp in the email header
timestamp_idx
. - a starting position of the invitation code in the email header
code_idx
.
Its instances are as follows:
- an email domain
domain_name
. - a Poseidon hash of the RSA public key
public_key_hash
. - a nullifier of the email
email_nullifier
. - a timestamp in the email header
timestamp
. - a masked subject where characters either in the email address or in the invitation code are replaced with zero
masked_subject_str
. - an account salt
account_salt
. - a flag whether the email header contains the invitation code
is_code_exist
.
yarn && yarn build
At packages/circuits
, make a build
directory, download the zip file from the following link, and place its unzipped directory under build
.
https://drive.google.com/file/d/1TChinAnHr9eV8H_OV9SVReF8Rvu6h1XH/view?usp=sharing
Then, move email_auth.zkey
in the unzipped directory params
to build
.
Then run the following command.
yarn test
yarn dev-setup
The email_auth.circom
makes constraints and computes the public output as follows.
- Assert that
signature
is valid forpadded_header
andpublic_key
. - Let
public_key_hash
bePoseidonHash(public_key)
. - Let
email_nullifier
bePoseidonHash(PoseidonHash(signature))
. - Let
from_addr
bepadded_header[from_addr_idx:from_addr_idx+256]
. - Let
subject
bepadded_header[subject_idx:subject_idx+MAX_SUBJECT_BYTES]
. - Let
domain_name
bepadded_header[domain_idx:domain_idx+255]
. - Let
is_time_exist
be 1 ifpadded_header
satisfies the regex of the timestamp field. - Let
timestamp_str
bepadded_header[timestamp_idx:timestamp_idx+10]
. - If
is_time_exist
is 1, lettimestamp
be an integer parsingtimestamp_str
as a digit string. Otherwise, lettimestamp
be zero. - Let
is_code_exist
be 1 ifpadded_header
satisfies the regex of the invitation code. - Let
code_str
bepadded_header[code_idx:code_idx+64]
. - Let
embedded_code
be an integer parsingcode_str
as a hex string. - If
is_code_exist
is 1, assert thatembedded_code
is equal toaccount_code
. - Let
account_salt
bePoseidonHash(from_addr|0..0, account_code, 0)
. - Let
masked_subject
be a string that removes the invitation code with the prefixcode_str
and one email address fromsubject
, if they appear insubject
.
Note that the email address in the subject is assumbed not to overlap with the invitation code.
A circuit to verify that a message in the email body, called command, is authorized by a user of an account salt, derived from an email address in the From field and a random field value called account code.
This is basically the same as the email_auth.circom
described above except for the following features:
- Instead of
subject_idx
, it additionally takes as a private input a padded email bodypadded_cleaned_body
and an index of the command in the email bodycommand_idx
. - It extracts a substring
command
between a prefix(<div id=3D\"[^\"]*zkemail[^\"]*\"[^>]*>)"
and a suffix</div>
frompadded_cleaned_body
. - It outputs
masked_command
instead ofmasked_subject
, which removes the invitation code with the prefix and one email address fromcommand
.