• Stars
    star
    160
  • Rank 234,703 (Top 5 %)
  • Language
    Jupyter Notebook
  • License
    GNU General Publi...
  • Created over 2 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Circom Circuits Library for Machine Learning

Circom Circuits Library for Machine Learning

Run npm run test to test all circomlib-ml circuit templates.

Disclaimer: This package is not affiliated with circom, circomlib, or iden3.

Description

Organisation

This respository contains 2 main folders:

  • circuits: all circom files containing ML templates and relevant util templates
circuits/
β”œβ”€β”€ ArgMax.circom
β”œβ”€β”€ AveragePooling2D.circom
β”œβ”€β”€ BatchNormalization2D.circom
β”œβ”€β”€ Conv1D.circom
β”œβ”€β”€ Conv2D.circom
β”œβ”€β”€ Dense.circom
β”œβ”€β”€ Flatten2D.circom
β”œβ”€β”€ MaxPooling2D.circom
β”œβ”€β”€ Poly.circom
β”œβ”€β”€ ReLU.circom
β”œβ”€β”€ SumPooling2D.circom
β”œβ”€β”€ circomlib
β”‚   β”œβ”€β”€ aliascheck.circom
β”‚   β”œβ”€β”€ babyjub.circom
β”‚   β”œβ”€β”€ binsum.circom
β”‚   β”œβ”€β”€ bitify.circom
β”‚   β”œβ”€β”€ comparators.circom
β”‚   β”œβ”€β”€ compconstant.circom
β”‚   β”œβ”€β”€ escalarmulany.circom
β”‚   β”œβ”€β”€ escalarmulfix.circom
β”‚   β”œβ”€β”€ mimc.circom
β”‚   β”œβ”€β”€ montgomery.circom
β”‚   β”œβ”€β”€ mux3.circom
β”‚   β”œβ”€β”€ sign.circom
β”‚   └── switcher.circom
β”œβ”€β”€ circomlib-matrix
β”‚   β”œβ”€β”€ matElemMul.circom
β”‚   β”œβ”€β”€ matElemSum.circom
β”‚   └── matMul.circom
β”œβ”€β”€ crypto
β”‚   β”œβ”€β”€ ecdh.circom
β”‚   β”œβ”€β”€ encrypt.circom
β”‚   └── publickey_derivation.circom
└── util.circom
  • test: containing all test circuits and unit tests
test/
β”œβ”€β”€ AveragePooling2D.js
β”œβ”€β”€ BatchNormalization.js
β”œβ”€β”€ Conv1D.js
β”œβ”€β”€ Conv2D.js
β”œβ”€β”€ Dense.js
β”œβ”€β”€ Flatten2D.js
β”œβ”€β”€ IsNegative.js
β”œβ”€β”€ IsPositive.js
β”œβ”€β”€ Max.js
β”œβ”€β”€ MaxPooling2D.js
β”œβ”€β”€ ReLU.js
β”œβ”€β”€ SumPooling2D.js
β”œβ”€β”€ circuits
β”‚   β”œβ”€β”€ AveragePooling2D_stride_test.circom
β”‚   β”œβ”€β”€ AveragePooling2D_test.circom
β”‚   β”œβ”€β”€ BatchNormalization_test.circom
β”‚   β”œβ”€β”€ Conv1D_test.circom
β”‚   β”œβ”€β”€ Conv2D_stride_test.circom
β”‚   β”œβ”€β”€ Conv2D_test.circom
β”‚   β”œβ”€β”€ Dense_test.circom
β”‚   β”œβ”€β”€ Flatten2D_test.circom
β”‚   β”œβ”€β”€ IsNegative_test.circom
β”‚   β”œβ”€β”€ IsPositive_test.circom
β”‚   β”œβ”€β”€ MaxPooling2D_stride_test.circom
β”‚   β”œβ”€β”€ MaxPooling2D_test.circom
β”‚   β”œβ”€β”€ Max_test.circom
β”‚   β”œβ”€β”€ ReLU_test.circom
β”‚   β”œβ”€β”€ SumPooling2D_stride_test.circom
β”‚   β”œβ”€β”€ SumPooling2D_test.circom
β”‚   β”œβ”€β”€ decryptMultiple_test.circom
β”‚   β”œβ”€β”€ decrypt_test.circom
β”‚   β”œβ”€β”€ ecdh_test.circom
β”‚   β”œβ”€β”€ encryptDecrypt_test.circom
β”‚   β”œβ”€β”€ encryptMultiple_test.circom
β”‚   β”œβ”€β”€ encrypt_test.circom
β”‚   β”œβ”€β”€ encrypted_mnist_latest_test.circom
β”‚   β”œβ”€β”€ mnist_convnet_test.circom
β”‚   β”œβ”€β”€ mnist_latest_precision_test.circom
β”‚   β”œβ”€β”€ mnist_latest_test.circom
β”‚   β”œβ”€β”€ mnist_poly_test.circom
β”‚   β”œβ”€β”€ mnist_test.circom
β”‚   β”œβ”€β”€ model1_test.circom
β”‚   └── publicKey_test.circom
β”œβ”€β”€ encryption.js
β”œβ”€β”€ mnist.js
β”œβ”€β”€ mnist_convnet.js
β”œβ”€β”€ mnist_latest.js
β”œβ”€β”€ mnist_latest_precision.js
β”œβ”€β”€ mnist_poly.js
└── model1.js

Template descriptions:

  • ArgMax.circom

    ArgMax(n) takes an input array of length n and returns an output signal correponds to the 0-based position index of the maximum element in the input.

  • AveragePooling2D.circom

    AveragePooling2D (nRows, nCols, nChannels, poolSize, strides, scaledInvPoolSize) takes an nRow-by-nCol-by-nChannels input array and performs average pooling on patches of poolSize-by-poolSize with step size strides. scaleInvPoolSize must be computed separately and supplied to the template. For example, a poolSize of 2, should have an scale factor of 1/(2*2) = 0.25 --> 25.

  • BatchNormalization2D.circom

    BatchNormalization2D(nRows, nCols, nChannels) performs Batch Normalization on a 2D input array. To avoid division, parameters in the layer is parametrized into a multiplying factor a and constant addition b, i.e. ax+b, where

    a = gamma/(moving_var+epsilon)**.5
    b = beta-gamma*moving_mean/(moving_var+epsilon)**.5
  • Conv1D.circom

    1D version of Conv2D

  • Conv2D.circom

    Conv2D (nRows, nCols, nChannels, nFilters, kernelSize, strides) performs 2D convolution on an nRow-by-nCol-by-nChannels input array with filters of kernelSize-by-kernelSize and step size of strides. Currently it works only for "valid" padding setting.

  • Dense.circom

    Dense (nInputs, nOutputs) performs simple matrix multiplication on the 1D input array of length nInputs and weights then adds biases to the output.

  • Flatten2D.circom

    Flatten2D (nRows, nCols, nChannels) flattens an nRow-by-nCol-by-nChannels input array.

  • MaxPooling2D.circom

    MaxPooling2D (nRows, nCols, nChannels, poolSize, strides)

  • Poly.circom

    Inspired by Ali, R. E., So, J., & Avestimehr, A. S. (2020), the Poly() template has been addded as a template to implement f(x)=x**2+x as an alternative activation layer to ReLU. The non-polynomial nature of ReLU activation results in a large number of constraints per layer. By replacing ReLU with the polynomial activation f(n,x)=x**2+n*x, the number of constraints drastically decrease with a slight performance tradeoff. A parameter n is required when declaring the component to adjust for the scaling of floating-point weights and biases into integers. See below for more information.

  • ReLU.circom

    ReLU() takes a single input and performs ReLU activation, i.e. max(0,x). This computation is much more expensive than Poly(). It's recommended to adapt your activation layers into polynomial activation to reduce the size of the final circuit.

  • SumPooling2D.circom

    Essentially AveragePooling2D with a constant scaling of poolSize*poolSize. This is preferred in circom to preserve precision and reduce computation.

  • util.circom

    IsPositive() treats zero as a positive number for better performance. If you want to use IsPositive() to check if a number is strictly positive, you can use the version in the in-code comments.

Weights and biases scaling:

  • Circom only accepts integers as signals, but Tensorflow weights and biases are floating-point numbers.
  • In order to simulate a neural network in Circom, weights must be scaled up by 10**m times. The larger m is, the higher the precision.
  • Subsequently, biases (if any) must be scaled up by 10**2m times or even more to maintain the correct output of the network.

An example is provided below.

Scaling example: mnist_poly

In models/mnist_poly.ipynb, a sample model of Conv2d-Poly-Dense layers was trained on the MNIST dataset. After training, the weights and biases must be properly scaled before inputting into the circuit:

  • Pixel values ranged from 0 to 255. In order for the polynomial activation approximation to work, these input values were scaled to 0.000 to 0.255 during model training. But the original integer values were scaled by 10**6 times as input to the circuit
    • Overall scaled by 10**9 times
  • Weights in the Conv2d layer were scaled by 10**9 times for higher precision. Subsequently, biases in the same layer must be scaled by (10**9)*(10**9)=10**18 times.
  • The linear term in the polynomial activation layer would also need to be adjusted by 10**18 times in order to match the scaling of the quadratic term. Hence we performed the acitvation with f(x)=x**2+(10**18)*x.
  • Weights in the Dense layer were scaled by 10**9 time for precision again.
  • Biases in the Dense layer had been omitted for simplcity, since ArgMax layer is not affected by the biases. However, if the biases were to be included (for example in a deeper network as an intermediate layer), they would have to be scaled by (10**9)**5=10**45 times to adjust correctly.

We can easily see that a deeper network would have to sacrifice precision, due to the limitation that Circom works under a finite field of modulo p which is around 254 bits. As log(2**254)~76, we need to make sure total scaling do not aggregate to exceed 10**76 (or even less) times. On average, a network with l layers should be scaled by less than or equal to 10**(76//l) times.

More Repositories

1

keras2circom

python tool to transpile a tf.keras model into a circom circuit
Jupyter Notebook
73
star
2

CodeFights

Codes for CodeFights (python)
Python
43
star
3

zkOTP

Zero-Knowledge OTP verification on chain
JavaScript
43
star
4

circomlib-matrix

Circuits library for matrix operations in circom
JavaScript
31
star
5

zkPhoto

Private authentic photo sharing using ZKP
Solidity
22
star
6

zkApp

Zero-Knowledge dApp Boilerplate
JavaScript
21
star
7

zkPuzzles

Puzzles using ZKP
Solidity
18
star
8

ZKaggleV2

Version 2 of ZKaggle, πŸ† Finalist of ETHGlobal FVM Space Warp Hack
Solidity
14
star
9

zkML

Demo application for circomlib-ml
Solidity
10
star
10

hello-noir

Noir boilerplate with hardhat and foundry
Solidity
10
star
11

hello-noir-ui

JavaScript
5
star
12

zk-hack-risc0-pw-check

Following "ZK HACK III - Building On-chain Apps Off-chain Using RISC Zero"
Rust
4
star
13

custom-dark-forest-ui

UI for socathie/custom-dark-forest
JavaScript
3
star
14

Quantum-Error-Correction

Simulation codes used for a final research project in Quantum Error Correction.
MATLAB
3
star
15

zk9-workshop

circom environment for ZKML workshop @ zkSummit9
Circom
2
star
16

grok-vs-llama

Solidity
2
star
17

snarkyjs-img

For ETHGlobal Tokyo
TypeScript
1
star
18

zkPhoto-ui

frontend for zkPhoto
JavaScript
1
star
19

near-circom

Hello Near template with Circom compatibility
JavaScript
1
star
20

laisee

JavaScript
1
star
21

zk-hack-noir

Following "ZK HACK III - Introduction to Noir - Aztec"
Roff
1
star
22

algorand-marketplace

JavaScript
1
star
23

securian

Winning submission of IEEE HK Web3 Hackathon 2022 by BUIDLers
TypeScript
1
star
24

JupyterLite

JupyterLite
Jupyter Notebook
1
star
25

custom-dark-forest

Minimal spawn only version of DF as an exercise to implement ZKP
JavaScript
1
star