Circom Circuits Library for Machine Learning
Last updated Jul 1, 2026
184
Stars
22
Forks
3
Issues
0
Stars/day
Attention Score
54
Language breakdown
Jupyter Notebook 59.0%
JavaScript 20.9%
Circom 16.4%
TypeScript 3.6%
Shell 0.0%
โธ Files
click to expand
README
[!WARNING]
README outdated and will be updated soon, see test folder for latest examples.
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
- This repository contains a library of circuit templates.
- You can read more about the circom language in the circom documentation webpage.
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 โ โโโ AveragePooling2Dstridetest.circom โ โโโ AveragePooling2D_test.circom โ โโโ BatchNormalization_test.circom โ โโโ Conv1D_test.circom โ โโโ Conv2Dstridetest.circom โ โโโ Conv2D_test.circom โ โโโ Dense_test.circom โ โโโ Flatten2D_test.circom โ โโโ IsNegative_test.circom โ โโโ IsPositive_test.circom โ โโโ MaxPooling2Dstridetest.circom โ โโโ MaxPooling2D_test.circom โ โโโ Max_test.circom โ โโโ ReLU_test.circom โ โโโ SumPooling2Dstridetest.circom โ โโโ SumPooling2D_test.circom โ โโโ decryptMultiple_test.circom โ โโโ decrypt_test.circom โ โโโ ecdh_test.circom โ โโโ encryptDecrypt_test.circom โ โโโ encryptMultiple_test.circom โ โโโ encrypt_test.circom โ โโโ encryptedmnistlatest_test.circom โ โโโ mnistconvnettest.circom โ โโโ mnistlatestprecision_test.circom โ โโโ mnistlatesttest.circom โ โโโ mnistpolytest.circom โ โโโ mnist_test.circom โ โโโ model1_test.circom โ โโโ publicKey_test.circom โโโ encryption.js โโโ mnist.js โโโ mnist_convnet.js โโโ mnist_latest.js โโโ mnistlatestprecision.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-gammamovingmean/(movingvar+epsilon)*.5
Conv1D.circom
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
Poly() template has been addded as a template to implement f(x)=x2+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)=x2+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
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**mtimes. The largermis, the higher the precision. - Subsequently, biases (if any) must be scaled up by
10**2mtimes or even more to maintain the correct output of the network.
Scaling example: mnist_poly
In models/mnistpoly.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**6times as input to the circuit
10**9 times
- Weights in the
Conv2dlayer were scaled by109times for higher precision. Subsequently, biases in the same layer must be scaled by(109)*(109)=1018times. - The linear term in the polynomial activation layer would also need to be adjusted by
1018times in order to match the scaling of the quadratic term. Hence we performed the acitvation withf(x)=x2+(10*18)x. - Weights in the
Denselayer were scaled by10**9time for precision again. - Biases in the
Denselayer had been omitted for simplcity, sinceArgMaxlayer 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(109)5=10**45times to adjust correctly.
p which is around 254 bits. As log(2254)~76, we need to make sure total scaling do not aggregate to exceed 1076 (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 in this category