@zkp2p/circuits-circom
v0.1.3-rc6
Published
Circom circuits for ZKP2P
Downloads
9
Keywords
Readme
circuits-circom
This folder contains the Circom circuits for ZKP2P
Venmo Emails
Venmo uses the same HTML template for its send, receive, request completed sent and request completed received emails. Although each email has different Venmo IDs, at the 4 spaces in the HTML template.
The HTML template:
<!-- actor name -->
<a style=3D"color:#0074DE; text-decoration:none" href=3D"ht=
tps://venmo.com/code?user_id=3D<VENMO_ID_1>&actor_id=3D<EMAIL_RECEIVER_VENMO_ID>=
xxxxxx">
You
</a>
<!-- action -->
<span>
paid
</span>
=20
<!-- recipient name -->
<a style=3D"color:#0074DE; text-decoration:none"
=20
href=3D"https://venmo.com/code?user_id=3D<VENMO_ID_2>=
xxxxx&actor_id=3D<EMAIL_RECEIVER_VENMO_ID>">
=20
Receiver's name
</a>
| Email | VENMO_ID_1 | VENMO_ID_2 | | ----- | ---------- | ---------- | | Venmo Send | Sender/Payer Venmo ID | Receiver/Payee Venmo ID | | Venmo Receive | Sender/Payer Venmo ID | Receiver/Payee Venmo ID | | Venmo Request Completed Send | Receiver/Payee Venmo ID | Sender/Payer Venmo ID | | Venmo Request Completed Receive | Receiver/Payee Venmo ID | Sender/Payer Venmo ID |
The protocol ONLY supports the SEND email type
Circuits
Venmo Send Email
Main circuit that onramper generates a proof of payment if offramper fails to generate proof above
- Verifies the DKIM signature (RSA, SHA256)
- Extracts from email, time of payment and amount for the Venmo transaction from the header
- Extract the payee ID and payer ID from the body
- Houses nullifier to prevent replay attacks
- Contains other order information to tie a proof to an order ID to prevent frontrunning
| Regex Config | Description |
| ------------------ | ---------------------------------------------------------------- |
| Offramper ID Regex | Extracts the Venmo payee ID from the payment sent email body to ensure the correct offramper is being paid |
| Onramper ID Regex | Extracts the Venmo payer ID from the payment sent email body to ensure the correct onramper sent the payment. This is to prevent man-in-the-middle attacks if onramper email is revealed to a 3rd party |
| Send Amount Regex | Extracts $ amount sent from from venmo payment sent email header to ensure its a Send email type and amount is greater than requested |
| Timestamp Regex | Extracts timestamp from venmo payment sent email header in order to ensure that email payment must be after on-chain intent timestamp |
| From Email Regex | Extracts from
email in venmo payment received email header to ensure that it is sent from [email protected] and not another Venmo email |
Venmo Registration
Main circuit that both onramper and offramper must generate a proof prior to using the protocol
- Verifies the DKIM signature (RSA, SHA256)
- Extracts from email and Venmo amount (restricts to a Send email type of the format:
You Paid $X to OFF_RAMPER_NAME
) from the header - Extracts actor ID (my Venmo ID) from the body
- Houses nullifier to prevent replay attacks
- Contains other order information to tie a proof to an order ID to prevent frontrunning
| Regex Config | Description |
| ------------------ | ---------------------------------------------------------------- |
| Actor ID Regex | Extracts the Venmo actor ID which is your email |
| Send Amount Regex | Extracts $ amount sent from from venmo payment sent email header to ensure its a Send email type and amount is greater than requested |
| From Email Regex | Extracts from
email in venmo payment received email header to ensure that it is sent from [email protected] and not another Venmo email |
Regexes
Venmo Payee and Payer ID
The Venmo Payee ID regex is generated using zk-regex which constrains ~330 bytes of HTML to prevent custom injection and index shifting attacks. Regex extracts 2 values: first one after user_id=3D
and second one after &actor_id=3D
{
"parts": [
{
"is_public": false,
"regex_def": "<!-- recipient name -->\r\n"
},
{
"is_public": false,
"regex_def": " <a style=3D\"color:#0074DE; text-decoration:none\"\r\n"
},
{
"is_public": false,
"regex_def": " =20\r\n"
},
{
"is_public": false,
"regex_def": " href=3D\"https://venmo.com/code\\?user_id=3D"
},
{
"is_public": true,
"regex_def": "(0|1|2|3|4|5|6|7|8|9|\r|\n|=)+"
},
{
"is_public": false,
"regex_def": "&actor_id=3D"
},
{
"is_public": true,
"regex_def": "(0|1|2|3|4|5|6|7|8|9)+"
},
{
"is_public": false,
"regex_def": "\">\r\n"
},
{
"is_public": false,
"regex_def": " =20\r\n"
},
{
"is_public": false,
"regex_def": " [^\r\n]+\r\n"
},
{
"is_public": false,
"regex_def": " </a>\r\n"
},
{
"is_public": false,
"regex_def": " =20\r\n"
},
{
"is_public": false,
"regex_def": " </div>\r\n"
},
{
"is_public": false,
"regex_def": " <!-- note -->\r\n"
}
]
}
Venmo Actor ID Regex
The Venmo Actor ID regex is generated using zk-regex which constrains ~330 bytes of HTML to prevent custom injection and index shifting attacks. Regex extracts after actor_id=3D
. Notice that the regex is exactly the same as above, except the revealed regex string is different
{
"parts": [
{
"is_public": false,
"regex_def": "<!-- recipient name -->\r\n"
},
{
"is_public": false,
"regex_def": " <a style=3D\"color:#0074DE; text-decoration:none\"\r\n"
},
{
"is_public": false,
"regex_def": " =20\r\n"
},
{
"is_public": false,
"regex_def": " href=3D\"https://venmo.com/code\\?user_id=3D"
},
{
"is_public": false,
"regex_def": "(0|1|2|3|4|5|6|7|8|9|\r|\n|=)+&actor_id=3D"
},
{
"is_public": true,
"regex_def": "(0|1|2|3|4|5|6|7|8|9)+"
},
{
"is_public": false,
"regex_def": "\">\r\n =20\r\n"
},
{
"is_public": false,
"regex_def": " [^\r\n]+\r\n"
},
{
"is_public": false,
"regex_def": " </a>\r\n"
},
{
"is_public": false,
"regex_def": " =20\r\n"
},
{
"is_public": false,
"regex_def": " </div>\r\n"
},
{
"is_public": false,
"regex_def": " <!-- note -->\r\n"
}
]
}
Venmo Send Amount
The Venmo Send Amount regex is generated using zk-regex which constrains the entire subject line to prevent index shifting attacks. Regex extracts after You paid
. Note that this regex limits the user to generate proofs using Send email types. For receive emails, the subject line will be X paid you $Y
{
"parts": [
{
"is_public": false,
"regex_def": "((\r\n)|^)subject:You paid "
},
{
"is_public": false,
"regex_def": "[^\r\n]+\\$"
},
{
"is_public": true,
"regex_def": "(0|1|2|3|4|5|6|7|8|9|\\.|,)+"
},
{
"is_public": false,
"regex_def": "\r\n"
}
]
}
| Regex Template | Description | |----------------|------------------------------------------------------------------------------------------------------------------------------| | VenmoPayeeID | Extracts the Venmo payee ID and payer ID from Send email types | | VenmoActorId | Extracts the actor ID (my ID) from Send email types | | VenmoSendAmount | Extracts the amount from a Send email type | | VenmoTimestamp | Extracts the timestamp from Venmo emails | | FromRegex | Extracts the from email ([email protected]) |
Usage
Generating Regexes
- Go to zk-regex and follow instructions
Compilation
- Create circuit.env
cp circuit.env.example circuit.env
- Run
yarn compile:TYPE
whereTYPE
issend
,receive
,registration
. This will generate the R1CS SYM and WASM files.
Generate witness
- Copy a
SEND
eml file intocircuits-circom/emls
for a given email type. Venmo send emails have the subject lineYou paid OFFRAMPER_NAME $X
. Make sure you are downloading the original email file. For example you can follow the following steps in Gmail. Name your Venmo emailvenmo_send.eml
. - In
circuits-circom
directory, runyarn gen-input:TYPE
whereTYPE
is eithersend
,registration
. This will generate an input file with the nameinput_EML_FILE_NAME.json
. - For development purposes, you only need to run up to this step
Run tests
- Inside the
circuits-circom
directory, first complete theCompilation
and generate input steps above for all the circuits. Tests will use theinput_EML_FILE_NAME.json
,.wasm
, and.r1cs
files. - Run
yarn test
. This will generate witnesses in thewtns
files prior to running tests. - Optionally, only run regex tests by running
yarn test test/regexes
Proving Key Generation
cd
intoscripts
and runcp entropy.env.example entropy.env
. Open the file and input your randomness. Entropy is needed to generate the proving key successfully- For production, run
yarn genkey:both:TYPE
which will generate both the chunked and nonchunked proving keys for the circuit - For dev, run
yarn genkey:chunked:unsafe
for chunked keys oryarn genkey:non-chunked:unsafe
, which will skip phase2 contribution and save keygen time (DO NOT USE IN PRODUCTION)
Generating Proofs
- To generate proofs on your local machine,
cd
intoscripts
and runCIRCUIT_NAME=YOUR_EMAIL_TYPE ./5_gen_proof.sh
- To generate proofs using RapidSnark serverside, run
yarn:genproof:TYPE
Security Assumptions
- Users do not share emails with each other. Treat your email like a private key
- Venmo does not change their email template drastically
- Admin has ability to update verification contracts over time