Skip to content

Commit

Permalink
updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Metachaser24 committed Apr 18, 2024
2 parents 5de6180 + 0cb90a3 commit 86bfdbe
Show file tree
Hide file tree
Showing 43 changed files with 3,769 additions and 2,253 deletions.
File renamed without changes.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Welcome to ZK-Email
![My Image](public/zkEmailLogo.jpg)

<p align="center">
<img src="docs/logo.jpg" width="300">
</p>

ZK Email is an application that allows for anonymous verification of email signatures while masking specific data. It enables verification of emails to/from specific domains or subsets of domains, as well as verification based on specific text in the email body. Our core SDK comes with libraries to assist with circuit generation as well as utility templates for general zk applications.

Expand Down
File renamed without changes
8 changes: 6 additions & 2 deletions docs/zk-email-docs/UsageGuide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,13 @@ To compile the circuit locally, you need to have Rust and Circom installed first


```bash
circom MyCircuit.circom -o --r1cs --wasm --sym --c
circom -l node_modules MyCircuit.circom -o --r1cs --wasm --sym --c --O0
```
*Note: You can add `-l` to specify the directory where the directive `include` should look for the circuits indicated. For our repo, use `circom -l node_modules` instead of `circom`. Additionally, we generally recommend using the `--O0` flag for optimization during compilation for beginners. However, if you're more experienced with Circom, feel free to use the `--O1` flag instead. It's important to avoid using the `--O2` flag as that is the default setting and it may lead to the deletion of additional constraints.*
*Note: You can add `-l` to specify the directory where the directive `include` should look for the circuits indicated. For our repo, if you are having errors, we recommend to use `circom -l node_modules` instead of `circom`.*

We generally recommend using the --O0 flag for ensuring there are no unintended underconstraints, but if you need to optimize constraints and understand what is being changed in circom, feel free to use --O1 instead. It's important to avoid using the `--O2` flag as that is the default setting and it may lead to the deletion of addition constraints.

Refer to these discussions on StackOverflow ([1](https://stackoverflow.com/questions/78136647/circom-does-not-create-a-constraint-for-addition/78177349#78177349), [2](https://stackoverflow.com/questions/77688466/circom-compiler-removes-crucial-constraint-after-simplication/78177354?noredirect=1#comment137833229_78177354)) for more information on constraint deletion.

After running this command, the circuit will be compiled into a `.r1cs` file, a `.wasm` file, and a `.sym` file. These files are used in the next steps to generate the proving and verifying keys, and to compute the witness.

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"version": "2.0.0",
"version": "4.0.0",
"license": "MIT",
"private": true,
"scripts": {
"test": "jest"
Expand Down
1 change: 1 addition & 0 deletions packages/circuits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,4 @@ EmailNullifier: Calculates the email nullifier using Poseidon hash.
</details>



28 changes: 14 additions & 14 deletions packages/circuits/lib/base64.circom
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,46 @@ template Base64Decode(byteLength) {
signal input in[charLength];
signal output out[byteLength];

component bits_in[charLength\4][4];
component bits_out[charLength\4][3];
component bitsIn[charLength\4][4];
component bitsOut[charLength\4][3];
component translate[charLength\4][4];

var idx = 0;
for (var i = 0; i < charLength; i += 4) {
for (var j = 0; j < 3; j++) {
bits_out[i\4][j] = Bits2Num(8);
bitsOut[i\4][j] = Bits2Num(8);
}

for (var j = 0; j < 4; j++) {
bits_in[i\4][j] = Num2Bits(6);
bitsIn[i\4][j] = Num2Bits(6);
translate[i\4][j] = Base64Lookup();
translate[i\4][j].in <== in[i+j];
translate[i\4][j].out ==> bits_in[i\4][j].in;
translate[i\4][j].out ==> bitsIn[i\4][j].in;
}

// Do the re-packing from four 6-bit words to three 8-bit words.
for (var j = 0; j < 6; j++) {
bits_out[i\4][0].in[j+2] <== bits_in[i\4][0].out[j];
bitsOut[i\4][0].in[j+2] <== bitsIn[i\4][0].out[j];
}
bits_out[i\4][0].in[0] <== bits_in[i\4][1].out[4];
bits_out[i\4][0].in[1] <== bits_in[i\4][1].out[5];
bitsOut[i\4][0].in[0] <== bitsIn[i\4][1].out[4];
bitsOut[i\4][0].in[1] <== bitsIn[i\4][1].out[5];

for (var j = 0; j < 4; j++) {
bits_out[i\4][1].in[j+4] <== bits_in[i\4][1].out[j];
bitsOut[i\4][1].in[j+4] <== bitsIn[i\4][1].out[j];
}
for (var j = 0; j < 4; j++) {
bits_out[i\4][1].in[j] <== bits_in[i\4][2].out[j+2];
bitsOut[i\4][1].in[j] <== bitsIn[i\4][2].out[j+2];
}

bits_out[i\4][2].in[6] <== bits_in[i\4][2].out[0];
bits_out[i\4][2].in[7] <== bits_in[i\4][2].out[1];
bitsOut[i\4][2].in[6] <== bitsIn[i\4][2].out[0];
bitsOut[i\4][2].in[7] <== bitsIn[i\4][2].out[1];
for (var j = 0; j < 6; j++) {
bits_out[i\4][2].in[j] <== bits_in[i\4][3].out[j];
bitsOut[i\4][2].in[j] <== bitsIn[i\4][3].out[j];
}

for (var j = 0; j < 3; j++) {
if (idx+j < byteLength) {
out[idx+j] <== bits_out[i\4][j].out;
out[idx+j] <== bitsOut[i\4][j].out;
}
}
idx += 3;
Expand Down
76 changes: 38 additions & 38 deletions packages/circuits/lib/rsa.circom
Original file line number Diff line number Diff line change
Expand Up @@ -103,76 +103,76 @@ template RSAPad(n, k) {

// The extra 152 bits comes from 0x3031300d060960864801650304020105000420
// This is due to padding from the RSASSA-PKCS1-v1_5 standard
var base_len = 408;
var msg_len = 256;
var baseLen = 408;
var msgLen = 256;

signal padded_message_bits[n*k];
signal paddedMessageBits[n*k];

component modulus_n2b[k];
component message_n2b[k];
signal modulus_bits[n*k];
signal message_bits[n*k];
component modulusN2B[k];
component messageN2B[k];
signal modulusBits[n*k];
signal messageBits[n*k];
for (var i = 0; i < k; i++) {
message_n2b[i] = Num2Bits(n);
message_n2b[i].in <== message[i];
messageN2B[i] = Num2Bits(n);
messageN2B[i].in <== message[i];
for (var j = 0; j < n; j++) {
message_bits[i*n+j] <== message_n2b[i].out[j];
messageBits[i*n+j] <== messageN2B[i].out[j];
}
modulus_n2b[i] = Num2Bits(n);
modulus_n2b[i].in <== modulus[i];
modulusN2B[i] = Num2Bits(n);
modulusN2B[i].in <== modulus[i];
for (var j = 0; j < n; j++) {
modulus_bits[i*n+j] <== modulus_n2b[i].out[j];
modulusBits[i*n+j] <== modulusN2B[i].out[j];
}
}

for (var i = msg_len; i < n*k; i++) {
message_bits[i] === 0;
for (var i = msgLen; i < n*k; i++) {
messageBits[i] === 0;
}

for (var i = 0; i < msg_len; i++) {
padded_message_bits[i] <== message_bits[i];
for (var i = 0; i < msgLen; i++) {
paddedMessageBits[i] <== messageBits[i];
}

for (var i = base_len; i < base_len + 8; i++) {
padded_message_bits[i] <== 0;
for (var i = baseLen; i < baseLen + 8; i++) {
paddedMessageBits[i] <== 0;
}

for (var i = msg_len; i < base_len; i++) {
padded_message_bits[i] <== (0x3031300d060960864801650304020105000420 >> (i - msg_len)) & 1;
for (var i = msgLen; i < baseLen; i++) {
paddedMessageBits[i] <== (0x3031300d060960864801650304020105000420 >> (i - msgLen)) & 1;
}

component modulus_zero[(n*k + 7 - (base_len + 8))\8];
component modulusZero[(n*k + 7 - (baseLen + 8))\8];
{
var modulus_prefix = 0;
for (var i = n*k - 1; i >= base_len + 8; i--) {
var modulusPrefix = 0;
for (var i = n*k - 1; i >= baseLen + 8; i--) {
if (i+8 < n*k) {
modulus_prefix += modulus_bits[i+8];
modulusPrefix += modulusBits[i+8];
if (i % 8 == 0) {
var idx = (i - (base_len + 8)) \ 8;
modulus_zero[idx] = IsZero();
modulus_zero[idx].in <== modulus_prefix;
padded_message_bits[i] <== 1-modulus_zero[idx].out;
var idx = (i - (baseLen + 8)) \ 8;
modulusZero[idx] = IsZero();
modulusZero[idx].in <== modulusPrefix;
paddedMessageBits[i] <== 1-modulusZero[idx].out;
} else {
padded_message_bits[i] <== padded_message_bits[i+1];
paddedMessageBits[i] <== paddedMessageBits[i+1];
}
} else {
padded_message_bits[i] <== 0;
paddedMessageBits[i] <== 0;
}
}
}

// The RFC guarantees at least 8 octets of 0xff padding.
assert(base_len + 8 + 65 <= n*k);
for (var i = base_len + 8; i < base_len + 8 + 65; i++) {
padded_message_bits[i] === 1;
assert(baseLen + 8 + 65 <= n*k);
for (var i = baseLen + 8; i < baseLen + 8 + 65; i++) {
paddedMessageBits[i] === 1;
}

component padded_message_b2n[k];
component passedMessageB2N[k];
for (var i = 0; i < k; i++) {
padded_message_b2n[i] = Bits2Num(n);
passedMessageB2N[i] = Bits2Num(n);
for (var j = 0; j < n; j++) {
padded_message_b2n[i].in[j] <== padded_message_bits[i*n+j];
passedMessageB2N[i].in[j] <== paddedMessageBits[i*n+j];
}
out[i] <== padded_message_b2n[i].out;
out[i] <== passedMessageB2N[i].out;
}
}
1 change: 1 addition & 0 deletions packages/circuits/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "@zk-email/circuits",
"version": "4.0.0",
"license": "MIT",
"scripts": {
"publish": "yarn npm publish --access=public",
"test": "NODE_OPTIONS=--max_old_space_size=8192 jest tests"
Expand Down
2 changes: 2 additions & 0 deletions packages/contracts/DKIMRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import "./interfaces/IDKIMRegistry.sol";
Input is DKIM pub key split into 17 chunks of 121 bits. You can use `helpers` package to fetch/split DKIM keys
*/
contract DKIMRegistry is IDKIMRegistry, Ownable {
constructor(address _signer) Ownable(_signer) { }

event DKIMPublicKeyHashRegistered(string domainName, bytes32 publicKeyHash);
event DKIMPublicKeyHashRevoked(bytes32 publicKeyHash);

Expand Down
1 change: 1 addition & 0 deletions packages/contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# @zk-email/contracts

## DKIMRegistry.sol

Expand Down
3 changes: 2 additions & 1 deletion packages/contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
src = './'
out = 'out'
allow_paths = ['../../node_modules']
solc_version = '0.8.21'
libs = ['../../node_modules']
solc_version = '0.8.21'
13 changes: 11 additions & 2 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
{
"name": "@zk-email/contracts",
"version": "5.0.2",
"version": "6.0.0",
"license": "MIT",
"scripts": {
"build": "forge build",
"publish": "yarn npm publish --access=public"
},
"dependencies": {
"@openzeppelin/contracts": "^4.9.3",
"@openzeppelin/contracts": "^5.0.0",
"dotenv": "^16.3.1"
},
"files": [
"DKIMRegistry.sol",
"/utils",
"/interfaces"
],
"devDependencies": {
"forge-std": "https://github.com/foundry-rs/forge-std"
}
}
5 changes: 3 additions & 2 deletions packages/contracts/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@openzeppelin=../../node_modules/@openzeppelin/contracts
@openzeppelin/contracts=../../node_modules/@openzeppelin/contracts
@openzeppelin/contracts-upgradeable=../../node_modules/@openzeppelin/contracts-upgradeable
@openzeppelin=../../node_modules/@openzeppelin/contracts
forge-std=../../node_modules/forge-std

27 changes: 27 additions & 0 deletions packages/contracts/test/DKIMRegistry.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import "@openzeppelin/contracts/utils/Strings.sol";
import "forge-std/src/Test.sol";
import "forge-std/src/console.sol";
import "../interfaces/IDKIMRegistry.sol";
import "../DKIMRegistry.sol";

/// @title ECDSAOwnedDKIMRegistry
/// @notice A DKIM Registry that could be updated by predefined ECDSA signer
contract TestDKIMRegistry is Test {
DKIMRegistry public dkimRegistry;
address public signer;

constructor() {
dkimRegistry = new DKIMRegistry(msg.sender);
signer = msg.sender;
}

function test_setDKIM() public {
vm.prank(signer);
dkimRegistry.setDKIMPublicKeyHash("test.com", "a81273981273bce922");
vm.stopPrank();
}
}

32 changes: 32 additions & 0 deletions packages/helpers/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"airbnb-base",
"airbnb-typescript/base"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module",
"project": "./tsconfig.json"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"max-len": ["error", { "code": 150 }],
"import/prefer-default-export": "off",
"no-await-in-loop": "off",
"no-restricted-syntax": "off",
"no-plusplus": "off",
"no-bitwise": "off",
"no-console": "off",
"no-continue": "off",
"@typescript-eslint/no-use-before-define": "off",
"prefer-destructuring": "off"
}
}
Loading

0 comments on commit 86bfdbe

Please sign in to comment.