Skip to content

Commit

Permalink
Merge pull request #9 from hollow-leaf/feat/zkTemplate
Browse files Browse the repository at this point in the history
feat: zk template
  • Loading branch information
kidneyweakx authored Aug 22, 2023
2 parents 5eec13e + 00971ad commit 8120e68
Show file tree
Hide file tree
Showing 12 changed files with 5,075 additions and 243 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ yarn-error.log*

# ui
dist/
artifacts/
.env
temp
11 changes: 11 additions & 0 deletions packages/zk-circuits/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
INFURA_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
PRIVATE_KEY="zzz"

# Block explorer API keys
ARBISCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
BSCSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
ETHERSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
GNOSISSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
OPTIMISM_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
POLYGONSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
SNOWTRACE_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
79 changes: 79 additions & 0 deletions packages/zk-circuits/circuits/circuits.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
pragma circom 2.0.0;

include "../node_modules/circomlib-ml/circuits/BatchNormalization2D.circom";
include "../node_modules/circomlib-ml/circuits/ArgMax.circom";
include "../node_modules/circomlib-ml/circuits/Dense.circom";
include "../node_modules/circomlib-ml/circuits/Conv2D.circom";
include "../node_modules/circomlib-ml/circuits/GlobalAveragePooling2D.circom";
include "../node_modules/circomlib-ml/circuits/AveragePooling2D.circom";

template Model() {
signal input in[50][50][1];
signal input conv2d_weights[3][3][1][4];
signal input conv2d_bias[4];
signal input batch_normalization_a[4];
signal input batch_normalization_b[4];
signal input dense_weights[4][2];
signal input dense_bias[2];
signal output out[1];

component conv2d = Conv2D(50, 50, 1, 4, 3, 1);
component batch_normalization = BatchNormalization2D(48, 48, 4);
component average_pooling2d = AveragePooling2D(48, 48, 4, 2, 2, 250000000000);
component global_average_pooling2d = GlobalAveragePooling2D(24, 24, 4, 1736111111);
component dense = Dense(4, 2);
component softmax = ArgMax(2);

for (var i0 = 0; i0 < 50; i0++) {
for (var i1 = 0; i1 < 50; i1++) {
for (var i2 = 0; i2 < 1; i2++) {
conv2d.in[i0][i1][i2] <== in[i0][i1][i2];
}}}
for (var i0 = 0; i0 < 3; i0++) {
for (var i1 = 0; i1 < 3; i1++) {
for (var i2 = 0; i2 < 1; i2++) {
for (var i3 = 0; i3 < 4; i3++) {
conv2d.weights[i0][i1][i2][i3] <== conv2d_weights[i0][i1][i2][i3];
}}}}
for (var i0 = 0; i0 < 4; i0++) {
conv2d.bias[i0] <== conv2d_bias[i0];
}
for (var i0 = 0; i0 < 48; i0++) {
for (var i1 = 0; i1 < 48; i1++) {
for (var i2 = 0; i2 < 4; i2++) {
batch_normalization.in[i0][i1][i2] <== conv2d.out[i0][i1][i2];
}}}
for (var i0 = 0; i0 < 4; i0++) {
batch_normalization.a[i0] <== batch_normalization_a[i0];
}
for (var i0 = 0; i0 < 4; i0++) {
batch_normalization.b[i0] <== batch_normalization_b[i0];
}
for (var i0 = 0; i0 < 48; i0++) {
for (var i1 = 0; i1 < 48; i1++) {
for (var i2 = 0; i2 < 4; i2++) {
average_pooling2d.in[i0][i1][i2] <== batch_normalization.out[i0][i1][i2];
}}}
for (var i0 = 0; i0 < 24; i0++) {
for (var i1 = 0; i1 < 24; i1++) {
for (var i2 = 0; i2 < 4; i2++) {
global_average_pooling2d.in[i0][i1][i2] <== average_pooling2d.out[i0][i1][i2];
}}}
for (var i0 = 0; i0 < 4; i0++) {
dense.in[i0] <== global_average_pooling2d.out[i0];
}
for (var i0 = 0; i0 < 4; i0++) {
for (var i1 = 0; i1 < 2; i1++) {
dense.weights[i0][i1] <== dense_weights[i0][i1];
}}
for (var i0 = 0; i0 < 2; i0++) {
dense.bias[i0] <== dense_bias[i0];
}
for (var i0 = 0; i0 < 2; i0++) {
softmax.in[i0] <== dense.out[i0];
}
out[0] <== softmax.out;

}

component main = Model();
67 changes: 67 additions & 0 deletions packages/zk-circuits/circuits/circuits.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"conv2d_weights": [
"403405242368",
"304365797376",
"235511644160",
"117679210496",
"369820598272",
"369435803648",
"221078290432",
"-425134292992",
"80874520576",
"245514108928",
"187810496512",
"-330524065792",
"-32316233728",
"-14922057728",
"-200911880192",
"1920103296",
"-41124859904",
"-115676495872",
"-215916150784",
"173553500160",
"-117569585152",
"-75012554752",
"-49569116160",
"-174658912256",
"-264812494848",
"-263167295488",
"-255334825984",
"359079608320",
"-243380076544",
"-393249521664",
"-161447706624",
"74104496128",
"-186532839424",
"-221273522176",
"-172075499520",
"-46639788032"
],
"conv2d_bias": ["0", "0", "0", "0"],
"batch_normalization_a": [
"11801251020800",
"7735594713088",
"5929726640128",
"3613041360896"
],
"batch_normalization_b": [
"245876039268925291102208",
"714476048871186646433792",
"1332232071569024141492224",
"430300893967944391852032"
],
"dense_weights": [
"-740124786688",
"1196192301056",
"-1536958136320",
"1008642883584",
"-403481919488",
"1017656573952",
"678901579776",
"-1020546908160"
],
"dense_bias": [
"-37879988551139837203300000819793879167869894840645006131200",
"37879962474107746081822244188339672384849354037826764668928"
]
}
153 changes: 153 additions & 0 deletions packages/zk-circuits/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { HardhatUserConfig } from 'hardhat/config'
import { NetworkUserConfig } from 'hardhat/types'
// hardhat plugin
import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-etherscan'
import '@nomicfoundation/hardhat-toolbox'
import 'hardhat-circom'

import { config as dotenvConfig } from 'dotenv'
import { resolve } from 'path'
import { loadTasks } from './scripts/helpers/hardhatConfigHelpers'

dotenvConfig({ path: resolve(__dirname, './.env') })

const taskFolder = ['tasks']
loadTasks(taskFolder)

const chainIds = {
ganache: 1337,
goerli: 5,
sepolia: 11155111,
hardhat: 31337,
quorum: 81712,
mainnet: 1,
avalanche: 43114,
bsc: 56,
'arbitrum-mainnet': 42161,
'polygon-mainnet': 137,
'optimism-goerli': 420,
'optimism-mainnet': 10,
'polygon-mumbai': 80001,
}

// Ensure that we have all the environment variables we need.
const pk: string | undefined = process.env.PRIVATE_KEY
if (!pk) {
throw new Error('Please set your pk in a .env file')
}

const infuraApiKey: string | undefined = process.env.INFURA_API_KEY
if (!infuraApiKey) {
throw new Error('Please set your INFURA_API_KEY in a .env file')
}

function getChainConfig (chain: keyof typeof chainIds): NetworkUserConfig {
let jsonRpcUrl: string
switch (chain) {
case 'avalanche':
jsonRpcUrl = 'https://api.avax.network/ext/bc/C/rpc'
break
case 'optimism-goerli':
jsonRpcUrl = 'https://goerli.optimism.io'
break
case 'quorum':
jsonRpcUrl = process.env.QUORUM_URL || ''
break
default:
jsonRpcUrl = `https://${chain}.infura.io/v3/${infuraApiKey}`
}
return {
accounts: [`0x${pk}`],
chainId: chainIds[chain],
url: jsonRpcUrl,
}
}

const config: HardhatUserConfig = {
defaultNetwork: 'hardhat',
networks: {
hardhat: {
chainId: chainIds.hardhat,
},
local: {
url: 'http://127.0.0.1:8545',
},
arbitrum: getChainConfig('arbitrum-mainnet'),
avalanche: getChainConfig('avalanche'),
bsc: getChainConfig('bsc'),
goerli: getChainConfig('goerli'),
sepolia: getChainConfig('sepolia'),
mainnet: getChainConfig('mainnet'),
optimism: getChainConfig('optimism-mainnet'),
'optimism-goerli': getChainConfig('optimism-goerli'),
'polygon-mainnet': getChainConfig('polygon-mainnet'),
'polygon-mumbai': getChainConfig('polygon-mumbai'),
},
paths: {
artifacts: './artifacts',
cache: './cache',
sources: './contracts',
tests: './test',
},
solidity: {
compilers: [
{
version: '0.8.18',
},
{
version: '0.6.11',
},
],
settings: {
metadata: {
// Not including the metadata hash
// https://github.com/paulrberg/hardhat-template/issues/31
bytecodeHash: 'none',
},
// Disable the optimizer when debugging
// https://hardhat.org/hardhat-network/#solidity-optimizer-support
optimizer: {
enabled: true,
runs: 800,
},
},
},
circom: {
inputBasePath: './circuits',
ptau: 'https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_20.ptau',
circuits: [
{
name: 'circuits',
},
],
},
etherscan: {
apiKey: {
arbitrumOne: process.env.ARBISCAN_API_KEY || '',
avalanche: process.env.SNOWTRACE_API_KEY || '',
bsc: process.env.BSCSCAN_API_KEY || '',
goerli: process.env.ETHERSCAN_API_KEY || '',
sepolia: process.env.ETHERSCAN_API_KEY || '',
mainnet: process.env.ETHERSCAN_API_KEY || '',
optimisticEthereum: process.env.OPTIMISM_API_KEY || '',
polygon: process.env.POLYGONSCAN_API_KEY || '',
optimisticGoerli: process.env.OPTIMISM_API_KEY || '',
polygonMumbai: process.env.POLYGONSCAN_API_KEY || '',
},
},

gasReporter: {
currency: 'USD',
gasPrice: 100,
enabled: process.env.REPORT_GAS as string === 'true',
excludeContracts: [],
src: './contracts',
},
typechain: {
outDir: 'typechain',
target: 'ethers-v5',
},
}

export default config
27 changes: 27 additions & 0 deletions packages/zk-circuits/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "zk-circuits",
"version": "0.1.0",
"main": "index.js",
"scripts": {
"circom:dev": "hardhat circom --deterministic --debug --verbose",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "kidneyweakx",
"license": "MIT",
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^2.0.2",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
"@openzeppelin/contracts": "^4.9.3",
"circomlib": "^2.0.5",
"circomlib-ml": "^1.4.4",
"circomlibjs": "^0.1.7",
"dotenv": "^16.3.1",
"ethers": "^5.7.0",
"hardhat": "^2.17.1",
"hardhat-circom": "^3.3.2",
"snarkjs": "^0.7.0",
"tsconfig": "workspace:*",
"typescript": "^4.9.4"
}
}
12 changes: 12 additions & 0 deletions packages/zk-circuits/scripts/helpers/hardhatConfigHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import fs from 'fs'
import path from 'path'

export const loadTasks = (taskFolders: string[]): void =>
taskFolders.forEach((folder) => {
const tasksPath = path.join(__dirname, '../', folder)
fs.readdirSync(tasksPath)
.filter((pth) => pth.includes('.ts') || pth.includes('.js'))
.forEach((task) => {
require(`${tasksPath}/${task}`)
})
})
11 changes: 11 additions & 0 deletions packages/zk-circuits/scripts/helpers/pathHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import fs from 'fs'
import path from 'path'

export const writeFileSync = (
dirPath: string,
fileName: string,
data: any,
) => {
fs.mkdirSync(dirPath, { recursive: true })
fs.writeFileSync(path.join(dirPath, fileName), data, 'utf8')
}
Loading

0 comments on commit 8120e68

Please sign in to comment.