rm autogenerated files: node_modules, artifacts, Cargo.lock

This commit is contained in:
2024-04-28 10:14:22 +02:00
parent 556d570e80
commit 160f094b73
149 changed files with 3 additions and 38216 deletions

3
.gitignore vendored
View File

@@ -1 +1,4 @@
/target /target
Cargo.lock
circom/artifacts
circom/node_modules

3171
Cargo.lock generated

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

16
circom/node_modules/.yarn-integrity generated vendored
View File

@@ -1,16 +0,0 @@
{
"systemParams": "linux-x64-108",
"modulesFolders": [
"node_modules"
],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [
"circomlib@^2.0.5"
],
"lockfileEntries": {
"circomlib@^2.0.5": "https://registry.yarnpkg.com/circomlib/-/circomlib-2.0.5.tgz#183c703e53ed7d011811842dbeeeb9819f4cc1d6"
},
"files": [],
"artifacts": {}
}

View File

@@ -1,63 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/calcoptimizedposeidonconsts/test_poseidon.js",
"cwd": "${workspaceFolder}/calcoptimizedposeidonconsts"
},
{
"type": "pwa-node",
"request": "launch",
"name": "Tests",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"cwd": "${workspaceFolder}",
"args": ["test/smtverifier.js"]
},
{
"type": "pwa-node",
"request": "launch",
"name": "Test Poseidon",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"cwd": "${workspaceFolder}",
"args": ["test/poseidoncircuit.js"]
},
{
"type": "pwa-node",
"request": "launch",
"name": "Test binsum",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"cwd": "${workspaceFolder}",
"args": ["test/binsum.js"]
},
{
"type": "pwa-node",
"request": "launch",
"name": "Test babyjub",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"cwd": "${workspaceFolder}",
"args": ["test/babyjub.js"]
}
]
}

View File

@@ -1,18 +0,0 @@
# CircomLib
## Description
- This repository contains a library of circuit templates.
- All files are copyrighted under 2018 0KIMS association and part of the free software [circom](https://github.com/iden3/circom) (Zero Knowledge Circuit Compiler).
- You can read more about the circom language in [the circom documentation webpage](https://docs.circom.io/).
## Organisation
This respository contains 5 folders:
- `circuits`: it contains the implementation of different cryptographic primitives in circom language.
- `calcpedersenbases`: set of functions in JavaScript used to find a set of points in [Baby Jubjub](https://github.com/barryWhiteHat/baby_jubjub) elliptic curve that serve as basis for the [Pedersen Hash](https://github.com/zcash/zcash/issues/2234).
- `doc`: it contains some circuit schemes in ASCII (must be opened with Monodraw, an ASCII art editor for Mac).
- `src`: it contains similar implementation of circuits in JavaScript.
- `test`: tests.
A description of the specific circuit templates for the `circuit` folder will be soon updated.

View File

@@ -1,830 +0,0 @@
# CircomLib/Circuits
## Description
- This folder contains circuit templates for standard operations and many cryptographic primitives.
- Below you can find specifications of each function. In the representation of elements, there are three tyes:
- Binary
- String
- Field element (the field is specified in each case. We consider 2 possible fields: Fp and Fr, where p... and r... .)
## Table of Contents
[TOC]
## Jordi
* compconstant - Returns 1 if `in` (expanded to binary array) > `ct`
* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1)
* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2
* BabyAdd - (`xout`,`yout`) = (`x1`,`y1`) + (`x2`,`y2`)
* BabyDbl - (`xout`,`yout`) = 2*(`x`,`y`)
* BabyCheck - check that (`x`,`y`) is on the curve
* binsub - binary subtraction
* gates - logical gates
* mimc - SNARK-friendly hash Minimal Multiplicative Complexity.
* https://eprint.iacr.org/2016/492.pdf
* zcash/zcash#2233
* smt - Sparse Merkle Tree
* https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751
* montgomery https://en.wikipedia.org/wiki/Montgomery_curve
## Circuits
### sha256
Folder containing the implementation of sha256 hash circuit.
### smt
Folder containing the circuit implementation of Sparse Merkle Trees.
### aliascheck
- `AliasCheck()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### babyjub
Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?)
- `BabyAdd()`
- DESCRIPTION
It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
- SCHEMA
```
var a var d
| |
| |
______v_________v_______
input x1 ----> | |
input y1 ----> | BabyAdd() | ----> output xout
input x2 ----> | | ----> output yout
input y2 ----> |________________________|
```
- INPUTS
| Input | Representation | Description | |
| ------------- | ------------- | ------------- | ------------- |
| `x1` | Bigint | Field element of Fp | First coordinate of a point (x1, y1) on E. |
| `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. |
| `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. |
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
- OUTPUT
| Input | Representation | Description | |
| ------------- | ------------- | ------------- | ------------- |
| `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
| `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
- BENCHMARKS (constraints)
- EXAMPLE
- `BabyDbl()`
- DESCRIPTION : doubles a point (`xout`,`yout`) = 2*(`x`,`y`).
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `BabyCheck()`
- DESCRIPTION : checks if a given point is in the curve.
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `BabyPbk()`
- DESCRIPTION: : given a private key, it returns the associated public key.
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### binsub
- `BinSub(n)`
- DESCRIPTION: binary substraction.
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### binsum
- `nbits(a)`
- DESCRIPTION : binary sum.
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `BinSum(n, ops)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### bitify
- `Num2Bits()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Num2Bits_strict()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Bits2Num()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Bits2Num_strict()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Num2BitsNeg()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### comparators
- `IsZero() `
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `IsEqual()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `ForceEqualIfEnabled()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `LessThan()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `GreaterThan()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `GreaterEqThan()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### compconstant
- `CompConstant(ct)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### eddsa
Edwards Digital Signature Algorithm in Baby Jubjbub (link a eddsa)
- `EdDSAVerifier(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### eddsamimc
- `EdDSAMiMCVerifier()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### eddsamimcsponge
- `EdDSAMiMCSpongeVerifier()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### eddsaposeidon
- `EdDSAPoseidonVerifier()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### escalarmul
- `EscalarMulWindow(base, k)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `EscalarMul(n, base)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### escalarmulany
- `Multiplexor2()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `BitElementMulAny()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `SegmentMulAny(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `EscalarMulAny(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### escalarmulfix
- `WindowMulFix()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `SegmentMulFix(nWindows)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `EscalarMulFix(n, BASE)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### escalarmulw4table
- `pointAdd`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `EscalarMulW4Table`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### gates
- `XOR`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `AND`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `OR`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `NOT`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `NAND`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `NOR`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `MultiAND`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### mimc
Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
- `MiMC7(nrounds)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `MultiMiMC7(nInputs, nRounds)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### mimcsponge
- `MiMCSponge(nInputs, nRounds, nOutputs)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `MiMCFeistel(nrounds)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### montgomery
- `Edwards2Montgomery()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Montgomery2Edwards()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `MontgomeryAdd()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `MontgomeryDouble()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### multiplexer
- `log2(a)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `EscalarProduct(w)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Decoder(w)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Multiplexer(wIn, nIn)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### mux1
- `MultiMux1(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Mux1()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### mux2
- `MultiMux2(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Mux2()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### mux3
- `MultiMux3(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Mux3()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### mux4
- `MultiMux4(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Mux4()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### pedersen_old
Old version of the Pedersen hash (do not use any
more?).
### pedersen
- `Window4()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Segment(nWindows)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Pedersen(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### pointbits
- `sqrt(n)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Bits2Point()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Bits2Point_Strict()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Point2Bits`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Point2Bits_Strict`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### poseidon
Implementation of Poseidon hash function (LINK)
- `Sigma()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Ark(t, C, r)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Mix(t, M)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
- `Poseidon(nInputs)`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### sign
- `Sign()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE
### switcher
- `Switcher()`
- DESCRIPTION
- SCHEMA
- INPUT
- OUTPUT
- BENCHMARKS
- EXAMPLE

View File

@@ -1,33 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "compconstant.circom";
template AliasCheck() {
signal input in[254];
component compConstant = CompConstant(-1);
for (var i=0; i<254; i++) in[i] ==> compConstant.in[i];
compConstant.out === 0;
}

View File

@@ -1,107 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "bitify.circom";
include "escalarmulfix.circom";
template BabyAdd() {
signal input x1;
signal input y1;
signal input x2;
signal input y2;
signal output xout;
signal output yout;
signal beta;
signal gamma;
signal delta;
signal tau;
var a = 168700;
var d = 168696;
beta <== x1*y2;
gamma <== y1*x2;
delta <== (-a*x1+y1)*(x2 + y2);
tau <== beta * gamma;
xout <-- (beta + gamma) / (1+ d*tau);
(1+ d*tau) * xout === (beta + gamma);
yout <-- (delta + a*beta - gamma) / (1-d*tau);
(1-d*tau)*yout === (delta + a*beta - gamma);
}
template BabyDbl() {
signal input x;
signal input y;
signal output xout;
signal output yout;
component adder = BabyAdd();
adder.x1 <== x;
adder.y1 <== y;
adder.x2 <== x;
adder.y2 <== y;
adder.xout ==> xout;
adder.yout ==> yout;
}
template BabyCheck() {
signal input x;
signal input y;
signal x2;
signal y2;
var a = 168700;
var d = 168696;
x2 <== x*x;
y2 <== y*y;
a*x2 + y2 === 1 + d*x2*y2;
}
// Extracts the public key from private key
template BabyPbk() {
signal input in;
signal output Ax;
signal output Ay;
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203
];
component pvkBits = Num2Bits(253);
pvkBits.in <== in;
component mulFix = EscalarMulFix(253, BASE8);
var i;
for (i=0; i<253; i++) {
mulFix.e[i] <== pvkBits.out[i];
}
Ax <== mulFix.out[0];
Ay <== mulFix.out[1];
}

View File

@@ -1,74 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
This component creates a binary substraction.
Main Constraint:
(in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1)) +
+ 2^n
- (in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1))
===
out[0] * 2^0 + out[1] * 2^1 + + out[n-1] *2^(n-1) + aux
out[0] * (out[0] - 1) === 0
out[1] * (out[0] - 1) === 0
.
.
.
out[n-1] * (out[n-1] - 1) === 0
aux * (aux-1) == 0
*/
pragma circom 2.0.0;
template BinSub(n) {
signal input in[2][n];
signal output out[n];
signal aux;
var lin = 2**n;
var lout = 0;
var i;
for (i=0; i<n; i++) {
lin = lin + in[0][i]*(2**i);
lin = lin - in[1][i]*(2**i);
}
for (i=0; i<n; i++) {
out[i] <-- (lin >> i) & 1;
// Ensure out is binary
out[i] * (out[i] - 1) === 0;
lout = lout + out[i]*(2**i);
}
aux <-- (lin >> n) & 1;
aux*(aux-1) === 0;
lout = lout + aux*(2**n);
// Ensure the sum;
lin === lout;
}

View File

@@ -1,101 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
Binary Sum
==========
This component creates a binary sum componet of ops operands and n bits each operand.
e is Number of carries: Depends on the number of operands in the input.
Main Constraint:
in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) +
+ in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) +
+ ..
+ in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) +
===
out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1)
To waranty binary outputs:
out[0] * (out[0] - 1) === 0
out[1] * (out[0] - 1) === 0
.
.
.
out[n+e-1] * (out[n+e-1] - 1) == 0
*/
/*
This function calculates the number of extra bits in the output to do the full sum.
*/
pragma circom 2.0.0;
function nbits(a) {
var n = 1;
var r = 0;
while (n-1<a) {
r++;
n *= 2;
}
return r;
}
template BinSum(n, ops) {
var nout = nbits((2**n -1)*ops);
signal input in[ops][n];
signal output out[nout];
var lin = 0;
var lout = 0;
var k;
var j;
var e2;
e2 = 1;
for (k=0; k<n; k++) {
for (j=0; j<ops; j++) {
lin += in[j][k] * e2;
}
e2 = e2 + e2;
}
e2 = 1;
for (k=0; k<nout; k++) {
out[k] <-- (lin >> k) & 1;
// Ensure out is binary
out[k] * (out[k] - 1) === 0;
lout += out[k] * e2;
e2 = e2+e2;
}
// Ensure the sum;
lin === lout;
}

View File

@@ -1,106 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "comparators.circom";
include "aliascheck.circom";
template Num2Bits(n) {
signal input in;
signal output out[n];
var lc1=0;
var e2=1;
for (var i = 0; i<n; i++) {
out[i] <-- (in >> i) & 1;
out[i] * (out[i] -1 ) === 0;
lc1 += out[i] * e2;
e2 = e2+e2;
}
lc1 === in;
}
template Num2Bits_strict() {
signal input in;
signal output out[254];
component aliasCheck = AliasCheck();
component n2b = Num2Bits(254);
in ==> n2b.in;
for (var i=0; i<254; i++) {
n2b.out[i] ==> out[i];
n2b.out[i] ==> aliasCheck.in[i];
}
}
template Bits2Num(n) {
signal input in[n];
signal output out;
var lc1=0;
var e2 = 1;
for (var i = 0; i<n; i++) {
lc1 += in[i] * e2;
e2 = e2 + e2;
}
lc1 ==> out;
}
template Bits2Num_strict() {
signal input in[254];
signal output out;
component aliasCheck = AliasCheck();
component b2n = Bits2Num(254);
for (var i=0; i<254; i++) {
in[i] ==> b2n.in[i];
in[i] ==> aliasCheck.in[i];
}
b2n.out ==> out;
}
template Num2BitsNeg(n) {
signal input in;
signal output out[n];
var lc1=0;
component isZero;
isZero = IsZero();
var neg = n == 0 ? 0 : 2**n - in;
for (var i = 0; i<n; i++) {
out[i] <-- (neg >> i) & 1;
out[i] * (out[i] -1 ) === 0;
lc1 += out[i] * 2**i;
}
in ==> isZero.in;
lc1 + isZero.out * 2**n === 2**n - in;
}

View File

@@ -1,141 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "bitify.circom";
include "binsum.circom";
template IsZero() {
signal input in;
signal output out;
signal inv;
inv <-- in!=0 ? 1/in : 0;
out <== -in*inv +1;
in*out === 0;
}
template IsEqual() {
signal input in[2];
signal output out;
component isz = IsZero();
in[1] - in[0] ==> isz.in;
isz.out ==> out;
}
template ForceEqualIfEnabled() {
signal input enabled;
signal input in[2];
component isz = IsZero();
in[1] - in[0] ==> isz.in;
(1 - isz.out)*enabled === 0;
}
/*
// N is the number of bits the input have.
// The MSF is the sign bit.
template LessThan(n) {
signal input in[2];
signal output out;
component num2Bits0;
component num2Bits1;
component adder;
adder = BinSum(n, 2);
num2Bits0 = Num2Bits(n);
num2Bits1 = Num2BitsNeg(n);
in[0] ==> num2Bits0.in;
in[1] ==> num2Bits1.in;
var i;
for (i=0;i<n;i++) {
num2Bits0.out[i] ==> adder.in[0][i];
num2Bits1.out[i] ==> adder.in[1][i];
}
adder.out[n-1] ==> out;
}
*/
template LessThan(n) {
assert(n <= 252);
signal input in[2];
signal output out;
component n2b = Num2Bits(n+1);
n2b.in <== in[0]+ (1<<n) - in[1];
out <== 1-n2b.out[n];
}
// N is the number of bits the input have.
// The MSF is the sign bit.
template LessEqThan(n) {
signal input in[2];
signal output out;
component lt = LessThan(n);
lt.in[0] <== in[0];
lt.in[1] <== in[1]+1;
lt.out ==> out;
}
// N is the number of bits the input have.
// The MSF is the sign bit.
template GreaterThan(n) {
signal input in[2];
signal output out;
component lt = LessThan(n);
lt.in[0] <== in[1];
lt.in[1] <== in[0];
lt.out ==> out;
}
// N is the number of bits the input have.
// The MSF is the sign bit.
template GreaterEqThan(n) {
signal input in[2];
signal output out;
component lt = LessThan(n);
lt.in[0] <== in[1];
lt.in[1] <== in[0]+1;
lt.out ==> out;
}

View File

@@ -1,74 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "bitify.circom";
// Returns 1 if in (in binary) > ct
template CompConstant(ct) {
signal input in[254];
signal output out;
signal parts[127];
signal sout;
var clsb;
var cmsb;
var slsb;
var smsb;
var sum=0;
var b = (1 << 128) -1;
var a = 1;
var e = 1;
var i;
for (i=0;i<127; i++) {
clsb = (ct >> (i*2)) & 1;
cmsb = (ct >> (i*2+1)) & 1;
slsb = in[i*2];
smsb = in[i*2+1];
if ((cmsb==0)&&(clsb==0)) {
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
} else if ((cmsb==0)&&(clsb==1)) {
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
} else if ((cmsb==1)&&(clsb==0)) {
parts[i] <== b*smsb*slsb - a*smsb + a;
} else {
parts[i] <== -a*smsb*slsb + a;
}
sum = sum + parts[i];
b = b -e;
a = a +e;
e = e*2;
}
sout <== sum;
component num2bits = Num2Bits(135);
num2bits.in <== sout;
out <== num2bits.out[127];
}

View File

@@ -1,139 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "compconstant.circom";
include "pointbits.circom";
include "pedersen.circom";
include "escalarmulany.circom";
include "escalarmulfix.circom";
template EdDSAVerifier(n) {
signal input msg[n];
signal input A[256];
signal input R8[256];
signal input S[256];
signal Ax;
signal Ay;
signal R8x;
signal R8y;
var i;
// Ensure S<Subgroup Order
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
for (i=0; i<254; i++) {
S[i] ==> compConstant.in[i];
}
compConstant.out === 0;
S[254] === 0;
S[255] === 0;
// Convert A to Field elements (And verify A)
component bits2pointA = Bits2Point_Strict();
for (i=0; i<256; i++) {
bits2pointA.in[i] <== A[i];
}
Ax <== bits2pointA.out[0];
Ay <== bits2pointA.out[1];
// Convert R8 to Field elements (And verify R8)
component bits2pointR8 = Bits2Point_Strict();
for (i=0; i<256; i++) {
bits2pointR8.in[i] <== R8[i];
}
R8x <== bits2pointR8.out[0];
R8y <== bits2pointR8.out[1];
// Calculate the h = H(R,A, msg)
component hash = Pedersen(512+n);
for (i=0; i<256; i++) {
hash.in[i] <== R8[i];
hash.in[256+i] <== A[i];
}
for (i=0; i<n; i++) {
hash.in[512+i] <== msg[i];
}
component point2bitsH = Point2Bits_Strict();
point2bitsH.in[0] <== hash.out[0];
point2bitsH.in[1] <== hash.out[1];
// Calculate second part of the right side: right2 = h*8*A
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
// the subgroup.
component dbl1 = BabyDbl();
dbl1.x <== Ax;
dbl1.y <== Ay;
component dbl2 = BabyDbl();
dbl2.x <== dbl1.xout;
dbl2.y <== dbl1.yout;
component dbl3 = BabyDbl();
dbl3.x <== dbl2.xout;
dbl3.y <== dbl2.yout;
// We check that A is not zero.
component isZero = IsZero();
isZero.in <== dbl3.x;
isZero.out === 0;
component mulAny = EscalarMulAny(256);
for (i=0; i<256; i++) {
mulAny.e[i] <== point2bitsH.out[i];
}
mulAny.p[0] <== dbl3.xout;
mulAny.p[1] <== dbl3.yout;
// Compute the right side: right = R8 + right2
component addRight = BabyAdd();
addRight.x1 <== R8x;
addRight.y1 <== R8y;
addRight.x2 <== mulAny.out[0];
addRight.y2 <== mulAny.out[1];
// Calculate left side of equation left = S*B8
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203
];
component mulFix = EscalarMulFix(256, BASE8);
for (i=0; i<256; i++) {
mulFix.e[i] <== S[i];
}
// Do the comparation left == right
mulFix.out[0] === addRight.xout;
mulFix.out[1] === addRight.yout;
}

View File

@@ -1,124 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "compconstant.circom";
include "pointbits.circom";
include "mimc.circom";
include "bitify.circom";
include "escalarmulany.circom";
include "escalarmulfix.circom";
template EdDSAMiMCVerifier() {
signal input enabled;
signal input Ax;
signal input Ay;
signal input S;
signal input R8x;
signal input R8y;
signal input M;
var i;
// Ensure S<Subgroup Order
component snum2bits = Num2Bits(253);
snum2bits.in <== S;
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
for (i=0; i<253; i++) {
snum2bits.out[i] ==> compConstant.in[i];
}
compConstant.in[253] <== 0;
compConstant.out === 0;
// Calculate the h = H(R,A, msg)
component hash = MultiMiMC7(5, 91);
hash.in[0] <== R8x;
hash.in[1] <== R8y;
hash.in[2] <== Ax;
hash.in[3] <== Ay;
hash.in[4] <== M;
hash.k <== 0;
component h2bits = Num2Bits_strict();
h2bits.in <== hash.out;
// Calculate second part of the right side: right2 = h*8*A
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
// the subgroup.
component dbl1 = BabyDbl();
dbl1.x <== Ax;
dbl1.y <== Ay;
component dbl2 = BabyDbl();
dbl2.x <== dbl1.xout;
dbl2.y <== dbl1.yout;
component dbl3 = BabyDbl();
dbl3.x <== dbl2.xout;
dbl3.y <== dbl2.yout;
// We check that A is not zero.
component isZero = IsZero();
isZero.in <== dbl3.x;
isZero.out === 0;
component mulAny = EscalarMulAny(254);
for (i=0; i<254; i++) {
mulAny.e[i] <== h2bits.out[i];
}
mulAny.p[0] <== dbl3.xout;
mulAny.p[1] <== dbl3.yout;
// Compute the right side: right = R8 + right2
component addRight = BabyAdd();
addRight.x1 <== R8x;
addRight.y1 <== R8y;
addRight.x2 <== mulAny.out[0];
addRight.y2 <== mulAny.out[1];
// Calculate left side of equation left = S*B8
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203
];
component mulFix = EscalarMulFix(253, BASE8);
for (i=0; i<253; i++) {
mulFix.e[i] <== snum2bits.out[i];
}
// Do the comparation left == right if enabled;
component eqCheckX = ForceEqualIfEnabled();
eqCheckX.enabled <== enabled;
eqCheckX.in[0] <== mulFix.out[0];
eqCheckX.in[1] <== addRight.xout;
component eqCheckY = ForceEqualIfEnabled();
eqCheckY.enabled <== enabled;
eqCheckY.in[0] <== mulFix.out[1];
eqCheckY.in[1] <== addRight.yout;
}

View File

@@ -1,124 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "compconstant.circom";
include "pointbits.circom";
include "mimcsponge.circom";
include "bitify.circom";
include "escalarmulany.circom";
include "escalarmulfix.circom";
template EdDSAMiMCSpongeVerifier() {
signal input enabled;
signal input Ax;
signal input Ay;
signal input S;
signal input R8x;
signal input R8y;
signal input M;
var i;
// Ensure S<Subgroup Order
component snum2bits = Num2Bits(253);
snum2bits.in <== S;
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
for (i=0; i<253; i++) {
snum2bits.out[i] ==> compConstant.in[i];
}
compConstant.in[253] <== 0;
compConstant.out === 0;
// Calculate the h = H(R,A, msg)
component hash = MiMCSponge(5, 220, 1);
hash.ins[0] <== R8x;
hash.ins[1] <== R8y;
hash.ins[2] <== Ax;
hash.ins[3] <== Ay;
hash.ins[4] <== M;
hash.k <== 0;
component h2bits = Num2Bits_strict();
h2bits.in <== hash.outs[0];
// Calculate second part of the right side: right2 = h*8*A
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
// the subgroup.
component dbl1 = BabyDbl();
dbl1.x <== Ax;
dbl1.y <== Ay;
component dbl2 = BabyDbl();
dbl2.x <== dbl1.xout;
dbl2.y <== dbl1.yout;
component dbl3 = BabyDbl();
dbl3.x <== dbl2.xout;
dbl3.y <== dbl2.yout;
// We check that A is not zero.
component isZero = IsZero();
isZero.in <== dbl3.x;
isZero.out === 0;
component mulAny = EscalarMulAny(254);
for (i=0; i<254; i++) {
mulAny.e[i] <== h2bits.out[i];
}
mulAny.p[0] <== dbl3.xout;
mulAny.p[1] <== dbl3.yout;
// Compute the right side: right = R8 + right2
component addRight = BabyAdd();
addRight.x1 <== R8x;
addRight.y1 <== R8y;
addRight.x2 <== mulAny.out[0];
addRight.y2 <== mulAny.out[1];
// Calculate left side of equation left = S*B8
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203
];
component mulFix = EscalarMulFix(253, BASE8);
for (i=0; i<253; i++) {
mulFix.e[i] <== snum2bits.out[i];
}
// Do the comparation left == right if enabled;
component eqCheckX = ForceEqualIfEnabled();
eqCheckX.enabled <== enabled;
eqCheckX.in[0] <== mulFix.out[0];
eqCheckX.in[1] <== addRight.xout;
component eqCheckY = ForceEqualIfEnabled();
eqCheckY.enabled <== enabled;
eqCheckY.in[0] <== mulFix.out[1];
eqCheckY.in[1] <== addRight.yout;
}

View File

@@ -1,123 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "compconstant.circom";
include "poseidon.circom";
include "bitify.circom";
include "escalarmulany.circom";
include "escalarmulfix.circom";
template EdDSAPoseidonVerifier() {
signal input enabled;
signal input Ax;
signal input Ay;
signal input S;
signal input R8x;
signal input R8y;
signal input M;
var i;
// Ensure S<Subgroup Order
component snum2bits = Num2Bits(253);
snum2bits.in <== S;
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
for (i=0; i<253; i++) {
snum2bits.out[i] ==> compConstant.in[i];
}
compConstant.in[253] <== 0;
compConstant.out*enabled === 0;
// Calculate the h = H(R,A, msg)
component hash = Poseidon(5);
hash.inputs[0] <== R8x;
hash.inputs[1] <== R8y;
hash.inputs[2] <== Ax;
hash.inputs[3] <== Ay;
hash.inputs[4] <== M;
component h2bits = Num2Bits_strict();
h2bits.in <== hash.out;
// Calculate second part of the right side: right2 = h*8*A
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
// the subgroup.
component dbl1 = BabyDbl();
dbl1.x <== Ax;
dbl1.y <== Ay;
component dbl2 = BabyDbl();
dbl2.x <== dbl1.xout;
dbl2.y <== dbl1.yout;
component dbl3 = BabyDbl();
dbl3.x <== dbl2.xout;
dbl3.y <== dbl2.yout;
// We check that A is not zero.
component isZero = IsZero();
isZero.in <== dbl3.x;
isZero.out*enabled === 0;
component mulAny = EscalarMulAny(254);
for (i=0; i<254; i++) {
mulAny.e[i] <== h2bits.out[i];
}
mulAny.p[0] <== dbl3.xout;
mulAny.p[1] <== dbl3.yout;
// Compute the right side: right = R8 + right2
component addRight = BabyAdd();
addRight.x1 <== R8x;
addRight.y1 <== R8y;
addRight.x2 <== mulAny.out[0];
addRight.y2 <== mulAny.out[1];
// Calculate left side of equation left = S*B8
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203
];
component mulFix = EscalarMulFix(253, BASE8);
for (i=0; i<253; i++) {
mulFix.e[i] <== snum2bits.out[i];
}
// Do the comparation left == right if enabled;
component eqCheckX = ForceEqualIfEnabled();
eqCheckX.enabled <== enabled;
eqCheckX.in[0] <== mulFix.out[0];
eqCheckX.in[1] <== addRight.xout;
component eqCheckY = ForceEqualIfEnabled();
eqCheckY.enabled <== enabled;
eqCheckY.in[0] <== mulFix.out[1];
eqCheckY.in[1] <== addRight.yout;
}

View File

@@ -1,166 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
┏━━━━━━━━━━━┓
┃ ┃
┃ ┃
(inx, iny) ══════════════════════════════════════════▶┃ EC Point ┃
┃ ╠═▶ (outx, outy)
╔══▶┃ Adder ┃
║ ┃ ┃
║ ┃ ┃
║ ┃ ┃
┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ║ ┗━━━━━━━━━━━┛
┃ ┃ ┃ ┃ ║
┃ ┃ ┃ ┃ ║
┃ ╠═══(p0x,p0y)═══▶┃ ┃ ║
┃ ╠═══(p1x,p1y)═══▶┃ ┃ ║
┃ ╠═══(p2x,p2y)═══▶┃ ┃ ║
┃ ╠═══(p3x,p3y)═══▶┃ ┃ ║
┃ ╠═══(p4x,p4y)═══▶┃ ┃ ║
┃ ╠═══(p5x,p5y)═══▶┃ ┃ ║
┃ ╠═══(p6x,p6y)═══▶┃ ┃ ║
┃ Constant ╠═══(p7x,p7y)═══▶┃ ┃ ║
┃ Points ┃ ┃ Mux4 ╠══╝
┃ ╠═══(p8x,p8y)═══▶┃ ┃
┃ ╠═══(p9x,p9y)═══▶┃ ┃
┃ ╠══(p10x,p10y)══▶┃ ┃
┃ ╠══(p11x,p11y)══▶┃ ┃
┃ ╠══(p12x,p12y)══▶┃ ┃
┃ ╠══(p13x,p13y)══▶┃ ┃
┃ ╠══(p14x,p14y)══▶┃ ┃
┃ ╠══(p15x,p15y)══▶┃ ┃
┃ ┃ ┃ ┃
┃ ┃ ┃ ┃
┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
▲ ▲ ▲ ▲
│ │ │ │
s0 ─────────────────────────────────┘ │ │ │
s1 ────────────────────────────────────┘ │ │
s2 ───────────────────────────────────────┘ │
s3 ──────────────────────────────────────────┘
*/
pragma circom 2.0.0;
include "mux4.circom";
include "escalarmulw4table.circom";
include "babyjub.circom";
template EscalarMulWindow(base, k) {
signal input in[2];
signal input sel[4];
signal output out[2];
var table[16][2];
component mux;
component adder;
var i;
table = EscalarMulW4Table(base, k);
mux = MultiMux4(2);
adder = BabyAdd();
for (i=0; i<4; i++) {
sel[i] ==> mux.s[i];
}
for (i=0; i<16; i++) {
mux.c[0][i] <== table[i][0];
mux.c[1][i] <== table[i][1];
}
in[0] ==> adder.x1;
in[1] ==> adder.y1;
mux.out[0] ==> adder.x2;
mux.out[1] ==> adder.y2;
adder.xout ==> out[0];
adder.yout ==> out[1];
}
/*
┏━━━━━━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━┓
┃ ┃ ┃ ┃ ┃ ┃
inp ════▶┃Window(0)┃═════▶┃Window(1)┃════════ . . . . ═════════▶┃ Window(nBlocks-1) ┃═════▶ out
┃ ┃ ┃ ┃ ┃ ┃
┗━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━┛
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
in[0]─────────┘ │ │ │ │ │ │ │ │ │ │ │
in[1]───────────┘ │ │ │ │ │ │ │ │ │ │
in[2]─────────────┘ │ │ │ │ │ │ │ 0 0
in[3]───────────────┘ │ │ │ │ │ │
in[4]──────────────────────────┘ │ │ │ │ │
in[5]────────────────────────────┘ │ │ │ │
in[6]──────────────────────────────┘ │ │ │
in[7]────────────────────────────────┘ │ │
. │ │
. │ │
in[n-2]─────────────────────────────────────────────────────────────────────┘ │
in[n-1]───────────────────────────────────────────────────────────────────────┘
*/
template EscalarMul(n, base) {
signal input in[n];
signal input inp[2]; // Point input to be added
signal output out[2];
var nBlocks = ((n-1)>>2)+1;
var i;
var j;
component windows[nBlocks];
// Construct the windows
for (i=0; i<nBlocks; i++) {
windows[i] = EscalarMulWindow(base, i);
}
// Connect the selectors
for (i=0; i<nBlocks; i++) {
for (j=0; j<4; j++) {
if (i*4+j >= n) {
windows[i].sel[j] <== 0;
} else {
windows[i].sel[j] <== in[i*4+j];
}
}
}
// Start with generator
windows[0].in[0] <== inp[0];
windows[0].in[1] <== inp[1];
for(i=0; i<nBlocks-1; i++) {
windows[i].out[0] ==> windows[i+1].in[0];
windows[i].out[1] ==> windows[i+1].in[1];
}
windows[nBlocks-1].out[0] ==> out[0];
windows[nBlocks-1].out[1] ==> out[1];
}

View File

@@ -1,197 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "montgomery.circom";
include "babyjub.circom";
include "comparators.circom";
template Multiplexor2() {
signal input sel;
signal input in[2][2];
signal output out[2];
out[0] <== (in[1][0] - in[0][0])*sel + in[0][0];
out[1] <== (in[1][1] - in[0][1])*sel + in[0][1];
}
template BitElementMulAny() {
signal input sel;
signal input dblIn[2];
signal input addIn[2];
signal output dblOut[2];
signal output addOut[2];
component doubler = MontgomeryDouble();
component adder = MontgomeryAdd();
component selector = Multiplexor2();
sel ==> selector.sel;
dblIn[0] ==> doubler.in[0];
dblIn[1] ==> doubler.in[1];
doubler.out[0] ==> adder.in1[0];
doubler.out[1] ==> adder.in1[1];
addIn[0] ==> adder.in2[0];
addIn[1] ==> adder.in2[1];
addIn[0] ==> selector.in[0][0];
addIn[1] ==> selector.in[0][1];
adder.out[0] ==> selector.in[1][0];
adder.out[1] ==> selector.in[1][1];
doubler.out[0] ==> dblOut[0];
doubler.out[1] ==> dblOut[1];
selector.out[0] ==> addOut[0];
selector.out[1] ==> addOut[1];
}
// p is montgomery point
// n must be <= 248
// returns out in twisted edwards
// Double is in montgomery to be linked;
template SegmentMulAny(n) {
signal input e[n];
signal input p[2];
signal output out[2];
signal output dbl[2];
component bits[n-1];
component e2m = Edwards2Montgomery();
p[0] ==> e2m.in[0];
p[1] ==> e2m.in[1];
var i;
bits[0] = BitElementMulAny();
e2m.out[0] ==> bits[0].dblIn[0];
e2m.out[1] ==> bits[0].dblIn[1];
e2m.out[0] ==> bits[0].addIn[0];
e2m.out[1] ==> bits[0].addIn[1];
e[1] ==> bits[0].sel;
for (i=1; i<n-1; i++) {
bits[i] = BitElementMulAny();
bits[i-1].dblOut[0] ==> bits[i].dblIn[0];
bits[i-1].dblOut[1] ==> bits[i].dblIn[1];
bits[i-1].addOut[0] ==> bits[i].addIn[0];
bits[i-1].addOut[1] ==> bits[i].addIn[1];
e[i+1] ==> bits[i].sel;
}
bits[n-2].dblOut[0] ==> dbl[0];
bits[n-2].dblOut[1] ==> dbl[1];
component m2e = Montgomery2Edwards();
bits[n-2].addOut[0] ==> m2e.in[0];
bits[n-2].addOut[1] ==> m2e.in[1];
component eadder = BabyAdd();
m2e.out[0] ==> eadder.x1;
m2e.out[1] ==> eadder.y1;
-p[0] ==> eadder.x2;
p[1] ==> eadder.y2;
component lastSel = Multiplexor2();
e[0] ==> lastSel.sel;
eadder.xout ==> lastSel.in[0][0];
eadder.yout ==> lastSel.in[0][1];
m2e.out[0] ==> lastSel.in[1][0];
m2e.out[1] ==> lastSel.in[1][1];
lastSel.out[0] ==> out[0];
lastSel.out[1] ==> out[1];
}
// This function assumes that p is in the subgroup and it is different to 0
template EscalarMulAny(n) {
signal input e[n]; // Input in binary format
signal input p[2]; // Point (Twisted format)
signal output out[2]; // Point (Twisted format)
var nsegments = (n-1)\148 +1;
var nlastsegment = n - (nsegments-1)*148;
component segments[nsegments];
component doublers[nsegments-1];
component m2e[nsegments-1];
component adders[nsegments-1];
component zeropoint = IsZero();
zeropoint.in <== p[0];
var s;
var i;
var nseg;
for (s=0; s<nsegments; s++) {
nseg = (s < nsegments-1) ? 148 : nlastsegment;
segments[s] = SegmentMulAny(nseg);
for (i=0; i<nseg; i++) {
e[s*148+i] ==> segments[s].e[i];
}
if (s==0) {
// force G8 point if input point is zero
segments[s].p[0] <== p[0] + (5299619240641551281634865583518297030282874472190772894086521144482721001553 - p[0])*zeropoint.out;
segments[s].p[1] <== p[1] + (16950150798460657717958625567821834550301663161624707787222815936182638968203 - p[1])*zeropoint.out;
} else {
doublers[s-1] = MontgomeryDouble();
m2e[s-1] = Montgomery2Edwards();
adders[s-1] = BabyAdd();
segments[s-1].dbl[0] ==> doublers[s-1].in[0];
segments[s-1].dbl[1] ==> doublers[s-1].in[1];
doublers[s-1].out[0] ==> m2e[s-1].in[0];
doublers[s-1].out[1] ==> m2e[s-1].in[1];
m2e[s-1].out[0] ==> segments[s].p[0];
m2e[s-1].out[1] ==> segments[s].p[1];
if (s==1) {
segments[s-1].out[0] ==> adders[s-1].x1;
segments[s-1].out[1] ==> adders[s-1].y1;
} else {
adders[s-2].xout ==> adders[s-1].x1;
adders[s-2].yout ==> adders[s-1].y1;
}
segments[s].out[0] ==> adders[s-1].x2;
segments[s].out[1] ==> adders[s-1].y2;
}
}
if (nsegments == 1) {
segments[0].out[0]*(1-zeropoint.out) ==> out[0];
segments[0].out[1]+(1-segments[0].out[1])*zeropoint.out ==> out[1];
} else {
adders[nsegments-2].xout*(1-zeropoint.out) ==> out[0];
adders[nsegments-2].yout+(1-adders[nsegments-2].yout)*zeropoint.out ==> out[1];
}
}

View File

@@ -1,299 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "mux3.circom";
include "montgomery.circom";
include "babyjub.circom";
/*
Window of 3 elements, it calculates
out = base + base*in[0] + 2*base*in[1] + 4*base*in[2]
out4 = 4*base
The result should be compensated.
*/
/*
The scalar is s = a0 + a1*2^3 + a2*2^6 + ...... + a81*2^243
First We calculate Q = B + 2^3*B + 2^6*B + ......... + 2^246*B
Then we calculate S1 = 2*2^246*B + (1 + a0)*B + (2^3 + a1)*B + .....+ (2^243 + a81)*B
And Finaly we compute the result: RES = SQ - Q
As you can see the input of the adders cannot be equal nor zero, except for the last
substraction that it's done in montgomery.
A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input
is the output of the windows that it's going to be <= 2^246*B
*/
template WindowMulFix() {
signal input in[3];
signal input base[2];
signal output out[2];
signal output out8[2]; // Returns 8*Base (To be linked)
component mux = MultiMux3(2);
mux.s[0] <== in[0];
mux.s[1] <== in[1];
mux.s[2] <== in[2];
component dbl2 = MontgomeryDouble();
component adr3 = MontgomeryAdd();
component adr4 = MontgomeryAdd();
component adr5 = MontgomeryAdd();
component adr6 = MontgomeryAdd();
component adr7 = MontgomeryAdd();
component adr8 = MontgomeryAdd();
// in[0] -> 1*BASE
mux.c[0][0] <== base[0];
mux.c[1][0] <== base[1];
// in[1] -> 2*BASE
dbl2.in[0] <== base[0];
dbl2.in[1] <== base[1];
mux.c[0][1] <== dbl2.out[0];
mux.c[1][1] <== dbl2.out[1];
// in[2] -> 3*BASE
adr3.in1[0] <== base[0];
adr3.in1[1] <== base[1];
adr3.in2[0] <== dbl2.out[0];
adr3.in2[1] <== dbl2.out[1];
mux.c[0][2] <== adr3.out[0];
mux.c[1][2] <== adr3.out[1];
// in[3] -> 4*BASE
adr4.in1[0] <== base[0];
adr4.in1[1] <== base[1];
adr4.in2[0] <== adr3.out[0];
adr4.in2[1] <== adr3.out[1];
mux.c[0][3] <== adr4.out[0];
mux.c[1][3] <== adr4.out[1];
// in[4] -> 5*BASE
adr5.in1[0] <== base[0];
adr5.in1[1] <== base[1];
adr5.in2[0] <== adr4.out[0];
adr5.in2[1] <== adr4.out[1];
mux.c[0][4] <== adr5.out[0];
mux.c[1][4] <== adr5.out[1];
// in[5] -> 6*BASE
adr6.in1[0] <== base[0];
adr6.in1[1] <== base[1];
adr6.in2[0] <== adr5.out[0];
adr6.in2[1] <== adr5.out[1];
mux.c[0][5] <== adr6.out[0];
mux.c[1][5] <== adr6.out[1];
// in[6] -> 7*BASE
adr7.in1[0] <== base[0];
adr7.in1[1] <== base[1];
adr7.in2[0] <== adr6.out[0];
adr7.in2[1] <== adr6.out[1];
mux.c[0][6] <== adr7.out[0];
mux.c[1][6] <== adr7.out[1];
// in[7] -> 8*BASE
adr8.in1[0] <== base[0];
adr8.in1[1] <== base[1];
adr8.in2[0] <== adr7.out[0];
adr8.in2[1] <== adr7.out[1];
mux.c[0][7] <== adr8.out[0];
mux.c[1][7] <== adr8.out[1];
out8[0] <== adr8.out[0];
out8[1] <== adr8.out[1];
out[0] <== mux.out[0];
out[1] <== mux.out[1];
}
/*
This component does a multiplication of a escalar times a fix base
Signals:
e: The scalar in bits
base: the base point in edwards format
out: The result
dbl: Point in Edwards to be linked to the next segment.
*/
template SegmentMulFix(nWindows) {
signal input e[nWindows*3];
signal input base[2];
signal output out[2];
signal output dbl[2];
var i;
var j;
// Convert the base to montgomery
component e2m = Edwards2Montgomery();
e2m.in[0] <== base[0];
e2m.in[1] <== base[1];
component windows[nWindows];
component adders[nWindows];
component cadders[nWindows];
// In the last step we add an extra doubler so that numbers do not match.
component dblLast = MontgomeryDouble();
for (i=0; i<nWindows; i++) {
windows[i] = WindowMulFix();
cadders[i] = MontgomeryAdd();
if (i==0) {
windows[i].base[0] <== e2m.out[0];
windows[i].base[1] <== e2m.out[1];
cadders[i].in1[0] <== e2m.out[0];
cadders[i].in1[1] <== e2m.out[1];
} else {
windows[i].base[0] <== windows[i-1].out8[0];
windows[i].base[1] <== windows[i-1].out8[1];
cadders[i].in1[0] <== cadders[i-1].out[0];
cadders[i].in1[1] <== cadders[i-1].out[1];
}
for (j=0; j<3; j++) {
windows[i].in[j] <== e[3*i+j];
}
if (i<nWindows-1) {
cadders[i].in2[0] <== windows[i].out8[0];
cadders[i].in2[1] <== windows[i].out8[1];
} else {
dblLast.in[0] <== windows[i].out8[0];
dblLast.in[1] <== windows[i].out8[1];
cadders[i].in2[0] <== dblLast.out[0];
cadders[i].in2[1] <== dblLast.out[1];
}
}
for (i=0; i<nWindows; i++) {
adders[i] = MontgomeryAdd();
if (i==0) {
adders[i].in1[0] <== dblLast.out[0];
adders[i].in1[1] <== dblLast.out[1];
} else {
adders[i].in1[0] <== adders[i-1].out[0];
adders[i].in1[1] <== adders[i-1].out[1];
}
adders[i].in2[0] <== windows[i].out[0];
adders[i].in2[1] <== windows[i].out[1];
}
component m2e = Montgomery2Edwards();
component cm2e = Montgomery2Edwards();
m2e.in[0] <== adders[nWindows-1].out[0];
m2e.in[1] <== adders[nWindows-1].out[1];
cm2e.in[0] <== cadders[nWindows-1].out[0];
cm2e.in[1] <== cadders[nWindows-1].out[1];
component cAdd = BabyAdd();
cAdd.x1 <== m2e.out[0];
cAdd.y1 <== m2e.out[1];
cAdd.x2 <== -cm2e.out[0];
cAdd.y2 <== cm2e.out[1];
cAdd.xout ==> out[0];
cAdd.yout ==> out[1];
windows[nWindows-1].out8[0] ==> dbl[0];
windows[nWindows-1].out8[1] ==> dbl[1];
}
/*
This component multiplies a escalar times a fixed point BASE (twisted edwards format)
Signals
e: The escalar in binary format
out: The output point in twisted edwards
*/
template EscalarMulFix(n, BASE) {
signal input e[n]; // Input in binary format
signal output out[2]; // Point (Twisted format)
var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246
var nlastsegment = n - (nsegments-1)*249;
component segments[nsegments];
component m2e[nsegments-1];
component adders[nsegments-1];
var s;
var i;
var nseg;
var nWindows;
for (s=0; s<nsegments; s++) {
nseg = (s < nsegments-1) ? 249 : nlastsegment;
nWindows = ((nseg - 1)\3)+1;
segments[s] = SegmentMulFix(nWindows);
for (i=0; i<nseg; i++) {
segments[s].e[i] <== e[s*249+i];
}
for (i = nseg; i<nWindows*3; i++) {
segments[s].e[i] <== 0;
}
if (s==0) {
segments[s].base[0] <== BASE[0];
segments[s].base[1] <== BASE[1];
} else {
m2e[s-1] = Montgomery2Edwards();
adders[s-1] = BabyAdd();
segments[s-1].dbl[0] ==> m2e[s-1].in[0];
segments[s-1].dbl[1] ==> m2e[s-1].in[1];
m2e[s-1].out[0] ==> segments[s].base[0];
m2e[s-1].out[1] ==> segments[s].base[1];
if (s==1) {
segments[s-1].out[0] ==> adders[s-1].x1;
segments[s-1].out[1] ==> adders[s-1].y1;
} else {
adders[s-2].xout ==> adders[s-1].x1;
adders[s-2].yout ==> adders[s-1].y1;
}
segments[s].out[0] ==> adders[s-1].x2;
segments[s].out[1] ==> adders[s-1].y2;
}
}
if (nsegments == 1) {
segments[0].out[0] ==> out[0];
segments[0].out[1] ==> out[1];
} else {
adders[nsegments-2].xout ==> out[0];
adders[nsegments-2].yout ==> out[1];
}
}

View File

@@ -1,52 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
function pointAdd(x1,y1,x2,y2) {
var a = 168700;
var d = 168696;
var res[2];
res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2);
res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2);
return res;
}
function EscalarMulW4Table(base, k) {
var out[16][2];
var i;
var p[2];
var dbl[2] = base;
for (i=0; i<k*4; i++) {
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
}
out[0][0] = 0;
out[0][1] = 1;
for (i=1; i<16; i++) {
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]);
out[i][0] = p[0];
out[i][1] = p[1];
}
return out;
}

View File

@@ -1,96 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template XOR() {
signal input a;
signal input b;
signal output out;
out <== a + b - 2*a*b;
}
template AND() {
signal input a;
signal input b;
signal output out;
out <== a*b;
}
template OR() {
signal input a;
signal input b;
signal output out;
out <== a + b - a*b;
}
template NOT() {
signal input in;
signal output out;
out <== 1 + in - 2*in;
}
template NAND() {
signal input a;
signal input b;
signal output out;
out <== 1 - a*b;
}
template NOR() {
signal input a;
signal input b;
signal output out;
out <== a*b + 1 - a - b;
}
template MultiAND(n) {
signal input in[n];
signal output out;
component and1;
component and2;
component ands[2];
if (n==1) {
out <== in[0];
} else if (n==2) {
and1 = AND();
and1.a <== in[0];
and1.b <== in[1];
out <== and1.out;
} else {
and2 = AND();
var n1 = n\2;
var n2 = n-n\2;
ands[0] = MultiAND(n1);
ands[1] = MultiAND(n2);
var i;
for (i=0; i<n1; i++) ands[0].in[i] <== in[i];
for (i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
and2.a <== ands[0].out;
and2.b <== ands[1].out;
out <== and2.out;
}
}

View File

@@ -1,156 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template MiMC7(nrounds) {
signal input x_in;
signal input k;
signal output out;
var c[91] = [
0,
20888961410941983456478427210666206549300505294776164667214940546594746570981,
15265126113435022738560151911929040668591755459209400716467504685752745317193,
8334177627492981984476504167502758309043212251641796197711684499645635709656,
1374324219480165500871639364801692115397519265181803854177629327624133579404,
11442588683664344394633565859260176446561886575962616332903193988751292992472,
2558901189096558760448896669327086721003508630712968559048179091037845349145,
11189978595292752354820141775598510151189959177917284797737745690127318076389,
3262966573163560839685415914157855077211340576201936620532175028036746741754,
17029914891543225301403832095880481731551830725367286980611178737703889171730,
4614037031668406927330683909387957156531244689520944789503628527855167665518,
19647356996769918391113967168615123299113119185942498194367262335168397100658,
5040699236106090655289931820723926657076483236860546282406111821875672148900,
2632385916954580941368956176626336146806721642583847728103570779270161510514,
17691411851977575435597871505860208507285462834710151833948561098560743654671,
11482807709115676646560379017491661435505951727793345550942389701970904563183,
8360838254132998143349158726141014535383109403565779450210746881879715734773,
12663821244032248511491386323242575231591777785787269938928497649288048289525,
3067001377342968891237590775929219083706800062321980129409398033259904188058,
8536471869378957766675292398190944925664113548202769136103887479787957959589,
19825444354178182240559170937204690272111734703605805530888940813160705385792,
16703465144013840124940690347975638755097486902749048533167980887413919317592,
13061236261277650370863439564453267964462486225679643020432589226741411380501,
10864774797625152707517901967943775867717907803542223029967000416969007792571,
10035653564014594269791753415727486340557376923045841607746250017541686319774,
3446968588058668564420958894889124905706353937375068998436129414772610003289,
4653317306466493184743870159523234588955994456998076243468148492375236846006,
8486711143589723036499933521576871883500223198263343024003617825616410932026,
250710584458582618659378487568129931785810765264752039738223488321597070280,
2104159799604932521291371026105311735948154964200596636974609406977292675173,
16313562605837709339799839901240652934758303521543693857533755376563489378839,
6032365105133504724925793806318578936233045029919447519826248813478479197288,
14025118133847866722315446277964222215118620050302054655768867040006542798474,
7400123822125662712777833064081316757896757785777291653271747396958201309118,
1744432620323851751204287974553233986555641872755053103823939564833813704825,
8316378125659383262515151597439205374263247719876250938893842106722210729522,
6739722627047123650704294650168547689199576889424317598327664349670094847386,
21211457866117465531949733809706514799713333930924902519246949506964470524162,
13718112532745211817410303291774369209520657938741992779396229864894885156527,
5264534817993325015357427094323255342713527811596856940387954546330728068658,
18884137497114307927425084003812022333609937761793387700010402412840002189451,
5148596049900083984813839872929010525572543381981952060869301611018636120248,
19799686398774806587970184652860783461860993790013219899147141137827718662674,
19240878651604412704364448729659032944342952609050243268894572835672205984837,
10546185249390392695582524554167530669949955276893453512788278945742408153192,
5507959600969845538113649209272736011390582494851145043668969080335346810411,
18177751737739153338153217698774510185696788019377850245260475034576050820091,
19603444733183990109492724100282114612026332366576932662794133334264283907557,
10548274686824425401349248282213580046351514091431715597441736281987273193140,
1823201861560942974198127384034483127920205835821334101215923769688644479957,
11867589662193422187545516240823411225342068709600734253659804646934346124945,
18718569356736340558616379408444812528964066420519677106145092918482774343613,
10530777752259630125564678480897857853807637120039176813174150229243735996839,
20486583726592018813337145844457018474256372770211860618687961310422228379031,
12690713110714036569415168795200156516217175005650145422920562694422306200486,
17386427286863519095301372413760745749282643730629659997153085139065756667205,
2216432659854733047132347621569505613620980842043977268828076165669557467682,
6309765381643925252238633914530877025934201680691496500372265330505506717193,
20806323192073945401862788605803131761175139076694468214027227878952047793390,
4037040458505567977365391535756875199663510397600316887746139396052445718861,
19948974083684238245321361840704327952464170097132407924861169241740046562673,
845322671528508199439318170916419179535949348988022948153107378280175750024,
16222384601744433420585982239113457177459602187868460608565289920306145389382,
10232118865851112229330353999139005145127746617219324244541194256766741433339,
6699067738555349409504843460654299019000594109597429103342076743347235369120,
6220784880752427143725783746407285094967584864656399181815603544365010379208,
6129250029437675212264306655559561251995722990149771051304736001195288083309,
10773245783118750721454994239248013870822765715268323522295722350908043393604,
4490242021765793917495398271905043433053432245571325177153467194570741607167,
19596995117319480189066041930051006586888908165330319666010398892494684778526,
837850695495734270707668553360118467905109360511302468085569220634750561083,
11803922811376367215191737026157445294481406304781326649717082177394185903907,
10201298324909697255105265958780781450978049256931478989759448189112393506592,
13564695482314888817576351063608519127702411536552857463682060761575100923924,
9262808208636973454201420823766139682381973240743541030659775288508921362724,
173271062536305557219323722062711383294158572562695717740068656098441040230,
18120430890549410286417591505529104700901943324772175772035648111937818237369,
20484495168135072493552514219686101965206843697794133766912991150184337935627,
19155651295705203459475805213866664350848604323501251939850063308319753686505,
11971299749478202793661982361798418342615500543489781306376058267926437157297,
18285310723116790056148596536349375622245669010373674803854111592441823052978,
7069216248902547653615508023941692395371990416048967468982099270925308100727,
6465151453746412132599596984628739550147379072443683076388208843341824127379,
16143532858389170960690347742477978826830511669766530042104134302796355145785,
19362583304414853660976404410208489566967618125972377176980367224623492419647,
1702213613534733786921602839210290505213503664731919006932367875629005980493,
10781825404476535814285389902565833897646945212027592373510689209734812292327,
4212716923652881254737947578600828255798948993302968210248673545442808456151,
7594017890037021425366623750593200398174488805473151513558919864633711506220,
18979889247746272055963929241596362599320706910852082477600815822482192194401,
13602139229813231349386885113156901793661719180900395818909719758150455500533
];
var t;
signal t2[nrounds];
signal t4[nrounds];
signal t6[nrounds];
signal t7[nrounds-1];
for (var i=0; i<nrounds; i++) {
t = (i==0) ? k+x_in : k + t7[i-1] + c[i];
t2[i] <== t*t;
t4[i] <== t2[i]*t2[i];
t6[i] <== t4[i]*t2[i];
if (i<nrounds-1) {
t7[i] <== t6[i]*t;
} else {
out <== t6[i]*t + k;
}
}
}
template MultiMiMC7(nInputs, nRounds) {
signal input in[nInputs];
signal input k;
signal output out;
signal r[nInputs +1];
component mims[nInputs];
r[0] <== k;
for (var i=0; i<nInputs; i++) {
mims[i] = MiMC7(nRounds);
mims[i].x_in <== in[i];
mims[i].k <== r[i];
r[i+1] <== r[i] + in[i] + mims[i].out;
}
out <== r[nInputs];
}

View File

@@ -1,293 +0,0 @@
pragma circom 2.0.0;
// implements MiMC-2n/n as hash using a sponge construction.
// log_5(21888242871839275222246405745257275088548364400416034343698204186575808495617) ~= 110
// => nRounds should be 220
template MiMCSponge(nInputs, nRounds, nOutputs) {
signal input ins[nInputs];
signal input k;
signal output outs[nOutputs];
var i;
// S = R||C
component S[nInputs + nOutputs - 1];
for (i = 0; i < nInputs; i++) {
S[i] = MiMCFeistel(nRounds);
S[i].k <== k;
if (i == 0) {
S[i].xL_in <== ins[0];
S[i].xR_in <== 0;
} else {
S[i].xL_in <== S[i-1].xL_out + ins[i];
S[i].xR_in <== S[i-1].xR_out;
}
}
outs[0] <== S[nInputs - 1].xL_out;
for (i = 0; i < nOutputs - 1; i++) {
S[nInputs + i] = MiMCFeistel(nRounds);
S[nInputs + i].k <== k;
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
S[nInputs + i].xR_in <== S[nInputs + i - 1].xR_out;
outs[i + 1] <== S[nInputs + i].xL_out;
}
}
template MiMCFeistel(nrounds) {
signal input xL_in;
signal input xR_in;
signal input k;
signal output xL_out;
signal output xR_out;
// doesn't contain the first and last round constants, which are always zero
var c_partial[218] = [
7120861356467848435263064379192047478074060781135320967663101236819528304084,
5024705281721889198577876690145313457398658950011302225525409148828000436681,
17980351014018068290387269214713820287804403312720763401943303895585469787384,
19886576439381707240399940949310933992335779767309383709787331470398675714258,
1213715278223786725806155661738676903520350859678319590331207960381534602599,
18162138253399958831050545255414688239130588254891200470934232514682584734511,
7667462281466170157858259197976388676420847047604921256361474169980037581876,
7207551498477838452286210989212982851118089401128156132319807392460388436957,
9864183311657946807255900203841777810810224615118629957816193727554621093838,
4798196928559910300796064665904583125427459076060519468052008159779219347957,
17387238494588145257484818061490088963673275521250153686214197573695921400950,
10005334761930299057035055370088813230849810566234116771751925093634136574742,
11897542014760736209670863723231849628230383119798486487899539017466261308762,
16771780563523793011283273687253985566177232886900511371656074413362142152543,
749264854018824809464168489785113337925400687349357088413132714480582918506,
3683645737503705042628598550438395339383572464204988015434959428676652575331,
7556750851783822914673316211129907782679509728346361368978891584375551186255,
20391289379084797414557439284689954098721219201171527383291525676334308303023,
18146517657445423462330854383025300323335289319277199154920964274562014376193,
8080173465267536232534446836148661251987053305394647905212781979099916615292,
10796443006899450245502071131975731672911747129805343722228413358507805531141,
5404287610364961067658660283245291234008692303120470305032076412056764726509,
4623894483395123520243967718315330178025957095502546813929290333264120223168,
16845753148201777192406958674202574751725237939980634861948953189320362207797,
4622170486584704769521001011395820886029808520586507873417553166762370293671,
16688277490485052681847773549197928630624828392248424077804829676011512392564,
11878652861183667748838188993669912629573713271883125458838494308957689090959,
2436445725746972287496138382764643208791713986676129260589667864467010129482,
1888098689545151571063267806606510032698677328923740058080630641742325067877,
148924106504065664829055598316821983869409581623245780505601526786791681102,
18875020877782404439294079398043479420415331640996249745272087358069018086569,
15189693413320228845990326214136820307649565437237093707846682797649429515840,
19669450123472657781282985229369348220906547335081730205028099210442632534079,
5521922218264623411380547905210139511350706092570900075727555783240701821773,
4144769320246558352780591737261172907511489963810975650573703217887429086546,
10097732913112662248360143041019433907849917041759137293018029019134392559350,
1720059427972723034107765345743336447947522473310069975142483982753181038321,
6302388219880227251325608388535181451187131054211388356563634768253301290116,
6745410632962119604799318394592010194450845483518862700079921360015766217097,
10858157235265583624235850660462324469799552996870780238992046963007491306222,
20241898894740093733047052816576694435372877719072347814065227797906130857593,
10165780782761211520836029617746977303303335603838343292431760011576528327409,
2832093654883670345969792724123161241696170611611744759675180839473215203706,
153011722355526826233082383360057587249818749719433916258246100068258954737,
20196970640587451358539129330170636295243141659030208529338914906436009086943,
3180973917010545328313139835982464870638521890385603025657430208141494469656,
17198004293191777441573635123110935015228014028618868252989374962722329283022,
7642160509228669138628515458941659189680509753651629476399516332224325757132,
19346204940546791021518535594447257347218878114049998691060016493806845179755,
11501810868606870391127866188394535330696206817602260610801897042898616817272,
3113973447392053821824427670386252797811804954746053461397972968381571297505,
6545064306297957002139416752334741502722251869537551068239642131448768236585,
5203908808704813498389265425172875593837960384349653691918590736979872578408,
2246692432011290582160062129070762007374502637007107318105405626910313810224,
11760570435432189127645691249600821064883781677693087773459065574359292849137,
5543749482491340532547407723464609328207990784853381797689466144924198391839,
8837549193990558762776520822018694066937602576881497343584903902880277769302,
12855514863299373699594410385788943772765811961581749194183533625311486462501,
5363660674689121676875069134269386492382220935599781121306637800261912519729,
13162342403579303950549728848130828093497701266240457479693991108217307949435,
916941639326869583414469202910306428966657806899788970948781207501251816730,
15618589556584434434009868216186115416835494805174158488636000580759692174228,
8959562060028569701043973060670353733575345393653685776974948916988033453971,
16390754464333401712265575949874369157699293840516802426621216808905079127650,
168282396747788514908709091757591226095443902501365500003618183905496160435,
8327443473179334761744301768309008451162322941906921742120510244986704677004,
17213012626801210615058753489149961717422101711567228037597150941152495100640,
10394369641533736715250242399198097296122982486516256408681925424076248952280,
17784386835392322654196171115293700800825771210400152504776806618892170162248,
16533189939837087893364000390641148516479148564190420358849587959161226782982,
18725396114211370207078434315900726338547621160475533496863298091023511945076,
7132325028834551397904855671244375895110341505383911719294705267624034122405,
148317947440800089795933930720822493695520852448386394775371401743494965187,
19001050671757720352890779127693793630251266879994702723636759889378387053056,
18824274411769830274877839365728651108434404855803844568234862945613766611460,
12771414330193951156383998390424063470766226667986423961689712557338777174205,
11332046574800279729678603488745295198038913503395629790213378101166488244657,
9607550223176946388146938069307456967842408600269548190739947540821716354749,
8756385288462344550200229174435953103162307705310807828651304665320046782583,
176061952957067086877570020242717222844908281373122372938833890096257042779,
12200212977482648306758992405065921724409841940671166017620928947866825250857,
10868453624107875516866146499877130701929063632959660262366632833504750028858,
2016095394399807253596787752134573207202567875457560571095586743878953450738,
21815578223768330433802113452339488275704145896544481092014911825656390567514,
4923772847693564777744725640710197015181591950368494148029046443433103381621,
1813584943682214789802230765734821149202472893379265320098816901270224589984,
10810123816265612772922113403831964815724109728287572256602010709288980656498,
1153669123397255702524721206511185557982017410156956216465120456256288427021,
5007518659266430200134478928344522649876467369278722765097865662497773767152,
2511432546938591792036639990606464315121646668029252285288323664350666551637,
32883284540320451295484135704808083452381176816565850047310272290579727564,
10484856914279112612610993418405543310546746652738541161791501150994088679557,
2026733759645519472558796412979210009170379159866522399881566309631434814953,
14731806221235869882801331463708736361296174006732553130708107037190460654379,
14740327483193277147065845135561988641238516852487657117813536909482068950652,
18787428285295558781869865751953016580493190547148386433580291216673009884554,
3804047064713122820157099453648459188816376755739202017447862327783289895072,
16709604795697901641948603019242067672006293290826991671766611326262532802914,
11061717085931490100602849654034280576915102867237101935487893025907907250695,
2821730726367472966906149684046356272806484545281639696873240305052362149654,
17467794879902895769410571945152708684493991588672014763135370927880883292655,
1571520786233540988201616650622796363168031165456869481368085474420849243232,
10041051776251223165849354194892664881051125330236567356945669006147134614302,
3981753758468103976812813304477670033098707002886030847251581853700311567551,
4365864398105436789177703571412645548020537580493599380018290523813331678900,
2391801327305361293476178683853802679507598622000359948432171562543560193350,
214219368547551689972421167733597094823289857206402800635962137077096090722,
18192064100315141084242006659317257023098826945893371479835220462302399655674,
15487549757142039139328911515400805508248576685795694919457041092150651939253,
10142447197759703415402259672441315777933858467700579946665223821199077641122,
11246573086260753259993971254725613211193686683988426513880826148090811891866,
6574066859860991369704567902211886840188702386542112593710271426704432301235,
11311085442652291634822798307831431035776248927202286895207125867542470350078,
20977948360215259915441258687649465618185769343138135384346964466965010873779,
792781492853909872425531014397300057232399608769451037135936617996830018501,
5027602491523497423798779154966735896562099398367163998686335127580757861872,
14595204575654316237672764823862241845410365278802914304953002937313300553572,
13973538843621261113924259058427434053808430378163734641175100160836376897004,
16395063164993626722686882727042150241125309409717445381854913964674649318585,
8465768840047024550750516678171433288207841931251654898809033371655109266663,
21345603324471810861925019445720576814602636473739003852898308205213912255830,
21171984405852590343970239018692870799717057961108910523876770029017785940991,
10761027113757988230637066281488532903174559953630210849190212601991063767647,
6678298831065390834922566306988418588227382406175769592902974103663687992230,
4993662582188632374202316265508850988596880036291765531885657575099537176757,
18364168158495573675698600238443218434246806358811328083953887470513967121206,
3506345610354615013737144848471391553141006285964325596214723571988011984829,
248732676202643792226973868626360612151424823368345645514532870586234380100,
10090204501612803176317709245679152331057882187411777688746797044706063410969,
21297149835078365363970699581821844234354988617890041296044775371855432973500,
16729368143229828574342820060716366330476985824952922184463387490091156065099,
4467191506765339364971058668792642195242197133011672559453028147641428433293,
8677548159358013363291014307402600830078662555833653517843708051504582990832,
1022951765127126818581466247360193856197472064872288389992480993218645055345,
1888195070251580606973417065636430294417895423429240431595054184472931224452,
4221265384902749246920810956363310125115516771964522748896154428740238579824,
2825393571154632139467378429077438870179957021959813965940638905853993971879,
19171031072692942278056619599721228021635671304612437350119663236604712493093,
10780807212297131186617505517708903709488273075252405602261683478333331220733,
18230936781133176044598070768084230333433368654744509969087239465125979720995,
16901065971871379877929280081392692752968612240624985552337779093292740763381,
146494141603558321291767829522948454429758543710648402457451799015963102253,
2492729278659146790410698334997955258248120870028541691998279257260289595548,
2204224910006646535594933495262085193210692406133533679934843341237521233504,
16062117410185840274616925297332331018523844434907012275592638570193234893570,
5894928453677122829055071981254202951712129328678534592916926069506935491729,
4947482739415078212217504789923078546034438919537985740403824517728200332286,
16143265650645676880461646123844627780378251900510645261875867423498913438066,
397690828254561723549349897112473766901585444153303054845160673059519614409,
11272653598912269895509621181205395118899451234151664604248382803490621227687,
15566927854306879444693061574322104423426072650522411176731130806720753591030,
14222898219492484180162096141564251903058269177856173968147960855133048449557,
16690275395485630428127725067513114066329712673106153451801968992299636791385,
3667030990325966886479548860429670833692690972701471494757671819017808678584,
21280039024501430842616328642522421302481259067470872421086939673482530783142,
15895485136902450169492923978042129726601461603404514670348703312850236146328,
7733050956302327984762132317027414325566202380840692458138724610131603812560,
438123800976401478772659663183448617575635636575786782566035096946820525816,
814913922521637742587885320797606426167962526342166512693085292151314976633,
12368712287081330853637674140264759478736012797026621876924395982504369598764,
2494806857395134874309386694756263421445039103814920780777601708371037591569,
16101132301514338989512946061786320637179843435886825102406248183507106312877,
6252650284989960032925831409804233477770646333900692286731621844532438095656,
9277135875276787021836189566799935097400042171346561246305113339462708861695,
10493603554686607050979497281838644324893776154179810893893660722522945589063,
8673089750662709235894359384294076697329948991010184356091130382437645649279,
9558393272910366944245875920138649617479779893610128634419086981339060613250,
19012287860122586147374214541764572282814469237161122489573881644994964647218,
9783723818270121678386992630754842961728702994964214799008457449989291229500,
15550788416669474113213749561488122552422887538676036667630838378023479382689,
15016165746156232864069722572047169071786333815661109750860165034341572904221,
6506225705710197163670556961299945987488979904603689017479840649664564978574,
10796631184889302076168355684722130903785890709107732067446714470783437829037,
19871836214837460419845806980869387567383718044439891735114283113359312279540,
20871081766843466343749609089986071784031203517506781251203251608363835140622,
5100105771517691442278432864090229416166996183792075307747582375962855820797,
8777887112076272395250620301071581171386440850451972412060638225741125310886,
5300440870136391278944213332144327695659161151625757537632832724102670898756,
1205448543652932944633962232545707633928124666868453915721030884663332604536,
5542499997310181530432302492142574333860449305424174466698068685590909336771,
11028094245762332275225364962905938096659249161369092798505554939952525894293,
19187314764836593118404597958543112407224947638377479622725713735224279297009,
17047263688548829001253658727764731047114098556534482052135734487985276987385,
19914849528178967155534624144358541535306360577227460456855821557421213606310,
2929658084700714257515872921366736697080475676508114973627124569375444665664,
15092262360719700162343163278648422751610766427236295023221516498310468956361,
21578580340755653236050830649990190843552802306886938815497471545814130084980,
1258781501221760320019859066036073675029057285507345332959539295621677296991,
3819598418157732134449049289585680301176983019643974929528867686268702720163,
8653175945487997845203439345797943132543211416447757110963967501177317426221,
6614652990340435611114076169697104582524566019034036680161902142028967568142,
19212515502973904821995111796203064175854996071497099383090983975618035391558,
18664315914479294273286016871365663486061896605232511201418576829062292269769,
11498264615058604317482574216318586415670903094838791165247179252175768794889,
10814026414212439999107945133852431304483604215416531759535467355316227331774,
17566185590731088197064706533119299946752127014428399631467913813769853431107,
14016139747289624978792446847000951708158212463304817001882956166752906714332,
8242601581342441750402731523736202888792436665415852106196418942315563860366,
9244680976345080074252591214216060854998619670381671198295645618515047080988,
12216779172735125538689875667307129262237123728082657485828359100719208190116,
10702811721859145441471328511968332847175733707711670171718794132331147396634,
6479667912792222539919362076122453947926362746906450079329453150607427372979,
15117544653571553820496948522381772148324367479772362833334593000535648316185,
6842203153996907264167856337497139692895299874139131328642472698663046726780,
12732823292801537626009139514048596316076834307941224506504666470961250728055,
6936272626871035740815028148058841877090860312517423346335878088297448888663,
17297554111853491139852678417579991271009602631577069694853813331124433680030,
16641596134749940573104316021365063031319260205559553673368334842484345864859,
7400481189785154329569470986896455371037813715804007747228648863919991399081,
2273205422216987330510475127669563545720586464429614439716564154166712854048,
15162538063742142685306302282127534305212832649282186184583465569986719234456,
5628039096440332922248578319648483863204530861778160259559031331287721255522,
16085392195894691829567913404182676871326863890140775376809129785155092531260,
14227467863135365427954093998621993651369686288941275436795622973781503444257,
18224457394066545825553407391290108485121649197258948320896164404518684305122,
274945154732293792784580363548970818611304339008964723447672490026510689427,
11050822248291117548220126630860474473945266276626263036056336623671308219529,
2119542016932434047340813757208803962484943912710204325088879681995922344971
];
var t;
signal t2[nrounds];
signal t4[nrounds];
signal xL[nrounds-1];
signal xR[nrounds-1];
var c;
for (var i=0; i<nrounds; i++) {
if ((i == 0) || (i == nrounds - 1)) {
c = 0;
} else {
c = c_partial[i - 1];
}
t = (i==0) ? k+xL_in : k + xL[i-1] + c;
t2[i] <== t*t;
t4[i] <== t2[i]*t2[i];
if (i<nrounds-1) {
var aux = (i==0) ? xR_in : xR[i-1] ;
xL[i] <== aux + t4[i]*t;
xR[i] <== (i==0) ? xL_in : xL[i-1];
} else {
xR_out <== xR[i-1] + t4[i]*t;
xL_out <== xL[i-1];
}
}
}

View File

@@ -1,142 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
Source: https://en.wikipedia.org/wiki/Montgomery_curve
1 + y 1 + y
[u, v] = [ ------- , ---------- ]
1 - y (1 - y)x
*/
pragma circom 2.0.0;
template Edwards2Montgomery() {
signal input in[2];
signal output out[2];
out[0] <-- (1 + in[1]) / (1 - in[1]);
out[1] <-- out[0] / in[0];
out[0] * (1-in[1]) === (1 + in[1]);
out[1] * in[0] === out[0];
}
/*
u u - 1
[x, y] = [ ---, ------- ]
v u + 1
*/
template Montgomery2Edwards() {
signal input in[2];
signal output out[2];
out[0] <-- in[0] / in[1];
out[1] <-- (in[0] - 1) / (in[0] + 1);
out[0] * in[1] === in[0];
out[1] * (in[0] + 1) === in[0] - 1;
}
/*
x2 - x1
lamda = ---------
y2 - y1
x3 + A + x1 + x2
x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------
B
y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 =>
=> y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 =>
=> y3 = lamda * ( x1 - x3 ) - y1
----------
y2 - y1
lamda = ---------
x2 - x1
x3 = B * lamda^2 - A - x1 -x2
y3 = lamda * ( x1 - x3 ) - y1
*/
template MontgomeryAdd() {
signal input in1[2];
signal input in2[2];
signal output out[2];
var a = 168700;
var d = 168696;
var A = (2 * (a + d)) / (a - d);
var B = 4 / (a - d);
signal lamda;
lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]);
lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]);
out[0] <== B*lamda*lamda - A - in1[0] -in2[0];
out[1] <== lamda * (in1[0] - out[0]) - in1[1];
}
/*
x1_2 = x1*x1
3*x1_2 + 2*A*x1 + 1
lamda = ---------------------
2*B*y1
x3 = B * lamda^2 - A - x1 -x1
y3 = lamda * ( x1 - x3 ) - y1
*/
template MontgomeryDouble() {
signal input in[2];
signal output out[2];
var a = 168700;
var d = 168696;
var A = (2 * (a + d)) / (a - d);
var B = 4 / (a - d);
signal lamda;
signal x1_2;
x1_2 <== in[0] * in[0];
lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]);
lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 );
out[0] <== B*lamda*lamda - A - 2*in[0];
out[1] <== lamda * (in[0] - out[0]) - in[1];
}

View File

@@ -1,115 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
// --> Assignation without constraint
// <-- Assignation without constraint
// === Constraint
// <== Assignation with constraint
// ==> Assignation with constraint
// All variables are members of the field F[p]
// https://github.com/zcash-hackworks/sapling-crypto
// https://github.com/ebfull/bellman
/*
function log2(a) {
if (a==0) {
return 0;
}
let n = 1;
let r = 1;
while (n<a) {
r++;
n *= 2;
}
return r;
}
*/
pragma circom 2.0.0;
template EscalarProduct(w) {
signal input in1[w];
signal input in2[w];
signal output out;
signal aux[w];
var lc = 0;
for (var i=0; i<w; i++) {
aux[i] <== in1[i]*in2[i];
lc = lc + aux[i];
}
out <== lc;
}
template Decoder(w) {
signal input inp;
signal output out[w];
signal output success;
var lc=0;
for (var i=0; i<w; i++) {
out[i] <-- (inp == i) ? 1 : 0;
out[i] * (inp-i) === 0;
lc = lc + out[i];
}
lc ==> success;
success * (success -1) === 0;
}
template Multiplexer(wIn, nIn) {
signal input inp[nIn][wIn];
signal input sel;
signal output out[wIn];
component dec = Decoder(nIn);
component ep[wIn];
for (var k=0; k<wIn; k++) {
ep[k] = EscalarProduct(nIn);
}
sel ==> dec.inp;
for (var j=0; j<wIn; j++) {
for (var k=0; k<nIn; k++) {
inp[k][j] ==> ep[j].in1[k];
dec.out[k] ==> ep[j].in2[k];
}
ep[j].out ==> out[j];
}
dec.success === 1;
}

View File

@@ -1,48 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template MultiMux1(n) {
signal input c[n][2]; // Constants
signal input s; // Selector
signal output out[n];
for (var i=0; i<n; i++) {
out[i] <== (c[i][1] - c[i][0])*s + c[i][0];
}
}
template Mux1() {
var i;
signal input c[2]; // Constants
signal input s; // Selector
signal output out;
component mux = MultiMux1(1);
for (i=0; i<2; i++) {
mux.c[0][i] <== c[i];
}
s ==> mux.s;
mux.out[0] ==> out;
}

View File

@@ -1,63 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template MultiMux2(n) {
signal input c[n][4]; // Constants
signal input s[2]; // Selector
signal output out[n];
signal a10[n];
signal a1[n];
signal a0[n];
signal a[n];
signal s10;
s10 <== s[1] * s[0];
for (var i=0; i<n; i++) {
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10;
a1[i] <== ( c[i][ 2]-c[i][ 0] ) * s[1];
a0[i] <== ( c[i][ 1]-c[i][ 0] ) * s[0];
a[i] <== ( c[i][ 0] );
out[i] <== ( a10[i] + a1[i] + a0[i] + a[i] );
}
}
template Mux2() {
var i;
signal input c[4]; // Constants
signal input s[2]; // Selector
signal output out;
component mux = MultiMux2(1);
for (i=0; i<4; i++) {
mux.c[0][i] <== c[i];
}
for (i=0; i<2; i++) {
s[i] ==> mux.s[i];
}
mux.out[0] ==> out;
}

View File

@@ -1,75 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template MultiMux3(n) {
signal input c[n][8]; // Constants
signal input s[3]; // Selector
signal output out[n];
signal a210[n];
signal a21[n];
signal a20[n];
signal a2[n];
signal a10[n];
signal a1[n];
signal a0[n];
signal a[n];
// 4 constrains for the intermediary variables
signal s10;
s10 <== s[1] * s[0];
for (var i=0; i<n; i++) {
a210[i] <== ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s10;
a21[i] <== ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) * s[1];
a20[i] <== ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) * s[0];
a2[i] <== ( c[i][ 4]-c[i][ 0] );
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10;
a1[i] <== ( c[i][ 2]-c[i][ 0] ) * s[1];
a0[i] <== ( c[i][ 1]-c[i][ 0] ) * s[0];
a[i] <== ( c[i][ 0] );
out[i] <== ( a210[i] + a21[i] + a20[i] + a2[i] ) * s[2] +
( a10[i] + a1[i] + a0[i] + a[i] );
}
}
template Mux3() {
var i;
signal input c[8]; // Constants
signal input s[3]; // Selector
signal output out;
component mux = MultiMux3(1);
for (i=0; i<8; i++) {
mux.c[0][i] <== c[i];
}
for (i=0; i<3; i++) {
s[i] ==> mux.s[i];
}
mux.out[0] ==> out;
}

View File

@@ -1,119 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template MultiMux4(n) {
signal input c[n][16]; // Constants
signal input s[4]; // Selector
signal output out[n];
signal a3210[n];
signal a321[n];
signal a320[n];
signal a310[n];
signal a32[n];
signal a31[n];
signal a30[n];
signal a3[n];
signal a210[n];
signal a21[n];
signal a20[n];
signal a10[n];
signal a2[n];
signal a1[n];
signal a0[n];
signal a[n];
// 4 constrains for the intermediary variables
signal s10;
s10 <== s[1] * s[0];
signal s20;
s20 <== s[2] * s[0];
signal s21;
s21 <== s[2] * s[1];
signal s210;
s210 <== s21 * s[0];
for (var i=0; i<n; i++) {
a3210[i] <== ( c[i][15]-c[i][14]-c[i][13]+c[i][12] - c[i][11]+c[i][10]+c[i][ 9]-c[i][ 8]
-c[i][ 7]+c[i][ 6]+c[i][ 5]-c[i][ 4] + c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s210;
a321[i] <== ( c[i][14]-c[i][12]-c[i][10]+c[i][ 8] - c[i][ 6]+c[i][ 4]+c[i][ 2]-c[i][ 0] ) * s21;
a320[i] <== ( c[i][13]-c[i][12]-c[i][ 9]+c[i][ 8] - c[i][ 5]+c[i][ 4]+c[i][ 1]-c[i][ 0] ) * s20;
a310[i] <== ( c[i][11]-c[i][10]-c[i][ 9]+c[i][ 8] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s10;
a32[i] <== ( c[i][12]-c[i][ 8]-c[i][ 4]+c[i][ 0] ) * s[2];
a31[i] <== ( c[i][10]-c[i][ 8]-c[i][ 2]+c[i][ 0] ) * s[1];
a30[i] <== ( c[i][ 9]-c[i][ 8]-c[i][ 1]+c[i][ 0] ) * s[0];
a3[i] <== ( c[i][ 8]-c[i][ 0] );
a210[i] <== ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s210;
a21[i] <== ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) * s21;
a20[i] <== ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) * s20;
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10;
a2[i] <== ( c[i][ 4]-c[i][ 0] ) * s[2];
a1[i] <== ( c[i][ 2]-c[i][ 0] ) * s[1];
a0[i] <== ( c[i][ 1]-c[i][ 0] ) * s[0];
a[i] <== ( c[i][ 0] );
out[i] <== ( a3210[i] + a321[i] + a320[i] + a310[i] + a32[i] + a31[i] + a30[i] + a3[i] ) * s[3] +
( a210[i] + a21[i] + a20[i] + a10[i] + a2[i] + a1[i] + a0[i] + a[i] );
/*
out[i] <== ( s210 * ( c[i][15]-c[i][14]-c[i][13]+c[i][12] - c[i][11]+c[i][10]+c[i][ 9]-c[i][ 8]
-c[i][ 7]+c[i][ 6]+c[i][ 5]-c[i][ 4] + c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) +
s21 * ( c[i][14]-c[i][12]-c[i][10]+c[i][ 8] - c[i][ 6]+c[i][ 4]+c[i][ 2]-c[i][ 0] ) +
s20 * ( c[i][13]-c[i][12]-c[i][ 9]+c[i][ 8] - c[i][ 5]+c[i][ 4]+c[i][ 1]-c[i][ 0] ) +
s10 * ( c[i][11]-c[i][10]-c[i][ 9]+c[i][ 8] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) +
s[2] * ( c[i][12]-c[i][ 8]-c[i][ 4]+c[i][ 0] ) +
s[1] * ( c[i][10]-c[i][ 8]-c[i][ 2]+c[i][ 0] ) +
s[0] * ( c[i][ 9]-c[i][ 8]-c[i][ 1]+c[i][ 0] ) +
( c[i][ 8]-c[i][ 0] ) ) * s[3] +
( s210 * ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) +
s21 * ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) +
s20 * ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) +
s10 * ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) +
s[2] * ( c[i][ 4]-c[i][ 0] ) +
s[1] * ( c[i][ 2]-c[i][ 0] ) +
s[0] * ( c[i][ 1]-c[i][ 0] ) +
( c[i][ 0] ));
*/
}
}
template Mux4() {
var i;
signal input c[16]; // Constants
signal input s[4]; // Selector
signal output out;
component mux = MultiMux4(1);
for (i=0; i<16; i++) {
mux.c[0][i] <== c[i];
}
for (i=0; i<4; i++) {
s[i] ==> mux.s[i];
}
mux.out[0] ==> out;
}

View File

@@ -1,257 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "montgomery.circom";
include "mux3.circom";
include "babyjub.circom";
template Window4() {
signal input in[4];
signal input base[2];
signal output out[2];
signal output out8[2]; // Returns 8*Base (To be linked)
component mux = MultiMux3(2);
mux.s[0] <== in[0];
mux.s[1] <== in[1];
mux.s[2] <== in[2];
component dbl2 = MontgomeryDouble();
component adr3 = MontgomeryAdd();
component adr4 = MontgomeryAdd();
component adr5 = MontgomeryAdd();
component adr6 = MontgomeryAdd();
component adr7 = MontgomeryAdd();
component adr8 = MontgomeryAdd();
// in[0] -> 1*BASE
mux.c[0][0] <== base[0];
mux.c[1][0] <== base[1];
// in[1] -> 2*BASE
dbl2.in[0] <== base[0];
dbl2.in[1] <== base[1];
mux.c[0][1] <== dbl2.out[0];
mux.c[1][1] <== dbl2.out[1];
// in[2] -> 3*BASE
adr3.in1[0] <== base[0];
adr3.in1[1] <== base[1];
adr3.in2[0] <== dbl2.out[0];
adr3.in2[1] <== dbl2.out[1];
mux.c[0][2] <== adr3.out[0];
mux.c[1][2] <== adr3.out[1];
// in[3] -> 4*BASE
adr4.in1[0] <== base[0];
adr4.in1[1] <== base[1];
adr4.in2[0] <== adr3.out[0];
adr4.in2[1] <== adr3.out[1];
mux.c[0][3] <== adr4.out[0];
mux.c[1][3] <== adr4.out[1];
// in[4] -> 5*BASE
adr5.in1[0] <== base[0];
adr5.in1[1] <== base[1];
adr5.in2[0] <== adr4.out[0];
adr5.in2[1] <== adr4.out[1];
mux.c[0][4] <== adr5.out[0];
mux.c[1][4] <== adr5.out[1];
// in[5] -> 6*BASE
adr6.in1[0] <== base[0];
adr6.in1[1] <== base[1];
adr6.in2[0] <== adr5.out[0];
adr6.in2[1] <== adr5.out[1];
mux.c[0][5] <== adr6.out[0];
mux.c[1][5] <== adr6.out[1];
// in[6] -> 7*BASE
adr7.in1[0] <== base[0];
adr7.in1[1] <== base[1];
adr7.in2[0] <== adr6.out[0];
adr7.in2[1] <== adr6.out[1];
mux.c[0][6] <== adr7.out[0];
mux.c[1][6] <== adr7.out[1];
// in[7] -> 8*BASE
adr8.in1[0] <== base[0];
adr8.in1[1] <== base[1];
adr8.in2[0] <== adr7.out[0];
adr8.in2[1] <== adr7.out[1];
mux.c[0][7] <== adr8.out[0];
mux.c[1][7] <== adr8.out[1];
out8[0] <== adr8.out[0];
out8[1] <== adr8.out[1];
out[0] <== mux.out[0];
out[1] <== - mux.out[1]*2*in[3] + mux.out[1]; // Negate y if in[3] is one
}
template Segment(nWindows) {
signal input in[nWindows*4];
signal input base[2];
signal output out[2];
var i;
var j;
// Convert the base to montgomery
component e2m = Edwards2Montgomery();
e2m.in[0] <== base[0];
e2m.in[1] <== base[1];
component windows[nWindows];
component doublers1[nWindows-1];
component doublers2[nWindows-1];
component adders[nWindows-1];
for (i=0; i<nWindows; i++) {
windows[i] = Window4();
for (j=0; j<4; j++) {
windows[i].in[j] <== in[4*i+j];
}
if (i==0) {
windows[i].base[0] <== e2m.out[0];
windows[i].base[1] <== e2m.out[1];
} else {
doublers1[i-1] = MontgomeryDouble();
doublers2[i-1] = MontgomeryDouble();
doublers1[i-1].in[0] <== windows[i-1].out8[0];
doublers1[i-1].in[1] <== windows[i-1].out8[1];
doublers2[i-1].in[0] <== doublers1[i-1].out[0];
doublers2[i-1].in[1] <== doublers1[i-1].out[1];
windows[i].base[0] <== doublers2[i-1].out[0];
windows[i].base[1] <== doublers2[i-1].out[1];
adders[i-1] = MontgomeryAdd();
if (i==1) {
adders[i-1].in1[0] <== windows[0].out[0];
adders[i-1].in1[1] <== windows[0].out[1];
} else {
adders[i-1].in1[0] <== adders[i-2].out[0];
adders[i-1].in1[1] <== adders[i-2].out[1];
}
adders[i-1].in2[0] <== windows[i].out[0];
adders[i-1].in2[1] <== windows[i].out[1];
}
}
component m2e = Montgomery2Edwards();
if (nWindows > 1) {
m2e.in[0] <== adders[nWindows-2].out[0];
m2e.in[1] <== adders[nWindows-2].out[1];
} else {
m2e.in[0] <== windows[0].out[0];
m2e.in[1] <== windows[0].out[1];
}
out[0] <== m2e.out[0];
out[1] <== m2e.out[1];
}
template Pedersen(n) {
signal input in[n];
signal output out[2];
var BASE[10][2] = [
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
[7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654],
[20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506],
[1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003],
[14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236],
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
];
var nSegments = ((n-1)\200)+1;
component segments[nSegments];
var i;
var j;
var nBits;
var nWindows;
for (i=0; i<nSegments; i++) {
nBits = (i == (nSegments-1)) ? n - (nSegments-1)*200 : 200;
nWindows = ((nBits - 1)\4)+1;
segments[i] = Segment(nWindows);
segments[i].base[0] <== BASE[i][0];
segments[i].base[1] <== BASE[i][1];
for (j = 0; j<nBits; j++) {
segments[i].in[j] <== in[i*200+j];
}
// Fill padding bits
for (j = nBits; j < nWindows*4; j++) {
segments[i].in[j] <== 0;
}
}
component adders[nSegments-1];
for (i=0; i<nSegments-1; i++) {
adders[i] = BabyAdd();
if (i==0) {
adders[i].x1 <== segments[0].out[0];
adders[i].y1 <== segments[0].out[1];
adders[i].x2 <== segments[1].out[0];
adders[i].y2 <== segments[1].out[1];
} else {
adders[i].x1 <== adders[i-1].xout;
adders[i].y1 <== adders[i-1].yout;
adders[i].x2 <== segments[i+1].out[0];
adders[i].y2 <== segments[i+1].out[1];
}
}
/*
coponent packPoint = PackPoint();
if (nSegments>1) {
packPoint.in[0] <== adders[nSegments-2].xout;
packPoint.in[1] <== adders[nSegments-2].yout;
} else {
packPoint.in[0] <== segments[0].out[0];
packPoint.in[1] <== segments[0].out[1];
}
out[0] <== packPoint.out[0];
out[1] <== packPoint.out[1];
*/
if (nSegments>1) {
out[0] <== adders[nSegments-2].xout;
out[1] <== adders[nSegments-2].yout;
} else {
out[0] <== segments[0].out[0];
out[1] <== segments[0].out[1];
}
}

View File

@@ -1,68 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "escalarmul.circom";
template Pedersen(n) {
signal input in[n];
signal output out[2];
var nexps = ((n-1) \ 250) + 1;
var nlastbits = n - (nexps-1)*250;
component escalarMuls[nexps];
var PBASE[10][2] = [
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
[7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654],
[20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506],
[1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003],
[14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236],
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
];
var i;
var j;
var nexpbits;
for (i=0; i<nexps; i++) {
nexpbits = (i == nexps-1) ? nlastbits : 250;
escalarMuls[i] = EscalarMul(nexpbits, PBASE[i]);
for (j=0; j<nexpbits; j++) {
escalarMuls[i].in[j] <== in[250*i + j];
}
if (i==0) {
escalarMuls[i].inp[0] <== 0;
escalarMuls[i].inp[1] <== 1;
} else {
escalarMuls[i].inp[0] <== escalarMuls[i-1].out[0];
escalarMuls[i].inp[1] <== escalarMuls[i-1].out[1];
}
}
escalarMuls[nexps-1].out[0] ==> out[0];
escalarMuls[nexps-1].out[1] ==> out[1];
}

View File

@@ -1,164 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "bitify.circom";
include "aliascheck.circom";
include "compconstant.circom";
include "babyjub.circom";
function sqrt(n) {
if (n == 0) {
return 0;
}
// Test that have solution
var res = n ** ((-1) >> 1);
// if (res!=1) assert(false, "SQRT does not exists");
if (res!=1) return 0;
var m = 28;
var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904;
var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111;
var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1);
var sq;
var i;
var b;
var j;
while ((r != 0)&&(t != 1)) {
sq = t*t;
i = 1;
while (sq!=1) {
i++;
sq = sq*sq;
}
// b = c ^ m-i-1
b = c;
for (j=0; j< m-i-1; j ++) b = b*b;
m = i;
c = b*b;
t = t*c;
r = r*b;
}
if (r < 0 ) {
r = -r;
}
return r;
}
template Bits2Point() {
signal input in[256];
signal output out[2];
}
template Bits2Point_Strict() {
signal input in[256];
signal output out[2];
var i;
// Check aliasing
component aliasCheckY = AliasCheck();
for (i=0; i<254; i++) {
aliasCheckY.in[i] <== in[i];
}
in[254] === 0;
component b2nY = Bits2Num(254);
for (i=0; i<254; i++) {
b2nY.in[i] <== in[i];
}
out[1] <== b2nY.out;
var a = 168700;
var d = 168696;
var y2 = out[1] * out[1];
var x = sqrt( (1-y2)/(a - d*y2) );
if (in[255] == 1) x = -x;
out[0] <-- x;
component babyCheck = BabyCheck();
babyCheck.x <== out[0];
babyCheck.y <== out[1];
component n2bX = Num2Bits(254);
n2bX.in <== out[0];
component aliasCheckX = AliasCheck();
for (i=0; i<254; i++) {
aliasCheckX.in[i] <== n2bX.out[i];
}
component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
for (i=0; i<254; i++) {
signCalc.in[i] <== n2bX.out[i];
}
signCalc.out === in[255];
}
template Point2Bits() {
signal input in[2];
signal output out[256];
}
template Point2Bits_Strict() {
signal input in[2];
signal output out[256];
var i;
component n2bX = Num2Bits(254);
n2bX.in <== in[0];
component n2bY = Num2Bits(254);
n2bY.in <== in[1];
component aliasCheckX = AliasCheck();
component aliasCheckY = AliasCheck();
for (i=0; i<254; i++) {
aliasCheckX.in[i] <== n2bX.out[i];
aliasCheckY.in[i] <== n2bY.out[i];
}
component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
for (i=0; i<254; i++) {
signCalc.in[i] <== n2bX.out[i];
}
for (i=0; i<254; i++) {
out[i] <== n2bY.out[i];
}
out[254] <== 0;
out[255] <== signCalc.out;
}

View File

@@ -1,208 +0,0 @@
pragma circom 2.0.0;
include "./poseidon_constants.circom";
template Sigma() {
signal input in;
signal output out;
signal in2;
signal in4;
in2 <== in*in;
in4 <== in2*in2;
out <== in4*in;
}
template Ark(t, C, r) {
signal input in[t];
signal output out[t];
for (var i=0; i<t; i++) {
out[i] <== in[i] + C[i + r];
}
}
template Mix(t, M) {
signal input in[t];
signal output out[t];
var lc;
for (var i=0; i<t; i++) {
lc = 0;
for (var j=0; j<t; j++) {
lc += M[j][i]*in[j];
}
out[i] <== lc;
}
}
template MixLast(t, M, s) {
signal input in[t];
signal output out;
var lc = 0;
for (var j=0; j<t; j++) {
lc += M[j][s]*in[j];
}
out <== lc;
}
template MixS(t, S, r) {
signal input in[t];
signal output out[t];
var lc = 0;
for (var i=0; i<t; i++) {
lc += S[(t*2-1)*r+i]*in[i];
}
out[0] <== lc;
for (var i=1; i<t; i++) {
out[i] <== in[i] + in[0] * S[(t*2-1)*r + t + i -1];
}
}
template PoseidonEx(nInputs, nOuts) {
signal input inputs[nInputs];
signal input initialState;
signal output out[nOuts];
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
// And rounded up to nearest integer that divides by t
var N_ROUNDS_P[16] = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68];
var t = nInputs + 1;
var nRoundsF = 8;
var nRoundsP = N_ROUNDS_P[t - 2];
var C[t*nRoundsF + nRoundsP] = POSEIDON_C(t);
var S[ N_ROUNDS_P[t-2] * (t*2-1) ] = POSEIDON_S(t);
var M[t][t] = POSEIDON_M(t);
var P[t][t] = POSEIDON_P(t);
component ark[nRoundsF];
component sigmaF[nRoundsF][t];
component sigmaP[nRoundsP];
component mix[nRoundsF-1];
component mixS[nRoundsP];
component mixLast[nOuts];
ark[0] = Ark(t, C, 0);
for (var j=0; j<t; j++) {
if (j>0) {
ark[0].in[j] <== inputs[j-1];
} else {
ark[0].in[j] <== initialState;
}
}
for (var r = 0; r < nRoundsF\2-1; r++) {
for (var j=0; j<t; j++) {
sigmaF[r][j] = Sigma();
if(r==0) {
sigmaF[r][j].in <== ark[0].out[j];
} else {
sigmaF[r][j].in <== mix[r-1].out[j];
}
}
ark[r+1] = Ark(t, C, (r+1)*t);
for (var j=0; j<t; j++) {
ark[r+1].in[j] <== sigmaF[r][j].out;
}
mix[r] = Mix(t,M);
for (var j=0; j<t; j++) {
mix[r].in[j] <== ark[r+1].out[j];
}
}
for (var j=0; j<t; j++) {
sigmaF[nRoundsF\2-1][j] = Sigma();
sigmaF[nRoundsF\2-1][j].in <== mix[nRoundsF\2-2].out[j];
}
ark[nRoundsF\2] = Ark(t, C, (nRoundsF\2)*t );
for (var j=0; j<t; j++) {
ark[nRoundsF\2].in[j] <== sigmaF[nRoundsF\2-1][j].out;
}
mix[nRoundsF\2-1] = Mix(t,P);
for (var j=0; j<t; j++) {
mix[nRoundsF\2-1].in[j] <== ark[nRoundsF\2].out[j];
}
for (var r = 0; r < nRoundsP; r++) {
sigmaP[r] = Sigma();
if (r==0) {
sigmaP[r].in <== mix[nRoundsF\2-1].out[0];
} else {
sigmaP[r].in <== mixS[r-1].out[0];
}
mixS[r] = MixS(t, S, r);
for (var j=0; j<t; j++) {
if (j==0) {
mixS[r].in[j] <== sigmaP[r].out + C[(nRoundsF\2+1)*t + r];
} else {
if (r==0) {
mixS[r].in[j] <== mix[nRoundsF\2-1].out[j];
} else {
mixS[r].in[j] <== mixS[r-1].out[j];
}
}
}
}
for (var r = 0; r < nRoundsF\2-1; r++) {
for (var j=0; j<t; j++) {
sigmaF[nRoundsF\2 + r][j] = Sigma();
if (r==0) {
sigmaF[nRoundsF\2 + r][j].in <== mixS[nRoundsP-1].out[j];
} else {
sigmaF[nRoundsF\2 + r][j].in <== mix[nRoundsF\2+r-1].out[j];
}
}
ark[ nRoundsF\2 + r + 1] = Ark(t, C, (nRoundsF\2+1)*t + nRoundsP + r*t );
for (var j=0; j<t; j++) {
ark[nRoundsF\2 + r + 1].in[j] <== sigmaF[nRoundsF\2 + r][j].out;
}
mix[nRoundsF\2 + r] = Mix(t,M);
for (var j=0; j<t; j++) {
mix[nRoundsF\2 + r].in[j] <== ark[nRoundsF\2 + r + 1].out[j];
}
}
for (var j=0; j<t; j++) {
sigmaF[nRoundsF-1][j] = Sigma();
sigmaF[nRoundsF-1][j].in <== mix[nRoundsF-2].out[j];
}
for (var i=0; i<nOuts; i++) {
mixLast[i] = MixLast(t,M,i);
for (var j=0; j<t; j++) {
mixLast[i].in[j] <== sigmaF[nRoundsF-1][j].out;
}
out[i] <== mixLast[i].out;
}
}
template Poseidon(nInputs) {
signal input inputs[nInputs];
signal output out;
component pEx = PoseidonEx(nInputs, 1);
pEx.initialState <== 0;
for (var i=0; i<nInputs; i++) {
pEx.inputs[i] <== inputs[i];
}
out <== pEx.out[0];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -1,97 +0,0 @@
pragma circom 2.0.0;
include "./poseidon_constants.circom";
template Sigma() {
signal input in;
signal output out;
signal in2;
signal in4;
in2 <== in*in;
in4 <== in2*in2;
out <== in4*in;
}
template Ark(t, C, r) {
signal input in[t];
signal output out[t];
for (var i=0; i<t; i++) {
out[i] <== in[i] + C[i + r];
}
}
template Mix(t, M) {
signal input in[t];
signal output out[t];
var lc;
for (var i=0; i<t; i++) {
lc = 0;
for (var j=0; j<t; j++) {
lc += M[i][j]*in[j];
}
out[i] <== lc;
}
}
template Poseidon(nInputs) {
signal input inputs[nInputs];
signal output out;
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
// And rounded up to nearest integer that divides by t
var N_ROUNDS_P[16] = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68];
var t = nInputs + 1;
var nRoundsF = 8;
var nRoundsP = N_ROUNDS_P[t - 2];
var C[t*(nRoundsF + nRoundsP)] = POSEIDON_C(t);
var M[t][t] = POSEIDON_M(t);
component ark[nRoundsF + nRoundsP];
component sigmaF[nRoundsF][t];
component sigmaP[nRoundsP];
component mix[nRoundsF + nRoundsP];
var k;
for (var i=0; i<nRoundsF + nRoundsP; i++) {
ark[i] = Ark(t, C, t*i);
for (var j=0; j<t; j++) {
if (i==0) {
if (j>0) {
ark[i].in[j] <== inputs[j-1];
} else {
ark[i].in[j] <== 0;
}
} else {
ark[i].in[j] <== mix[i-1].out[j];
}
}
if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) {
k = i < nRoundsF/2 ? i : i - nRoundsP;
mix[i] = Mix(t, M);
for (var j=0; j<t; j++) {
sigmaF[k][j] = Sigma();
sigmaF[k][j].in <== ark[i].out[j];
mix[i].in[j] <== sigmaF[k][j].out;
}
} else {
k = i - nRoundsF/2;
mix[i] = Mix(t, M);
sigmaP[k] = Sigma();
sigmaP[k].in <== ark[i].out[0];
mix[i].in[0] <== sigmaP[k].out;
for (var j=1; j<t; j++) {
mix[i].in[j] <== ark[i].out[j];
}
}
}
out <== mix[nRoundsF + nRoundsP -1].out[0];
}

View File

@@ -1,47 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/* Ch
000 0
001 1
010 0
011 1
100 0
101 0
110 1
111 1
out = a&b ^ (!a)&c =>
out = a*(b-c) + c
*/
pragma circom 2.0.0;
template Ch_t(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
for (var k=0; k<n; k++) {
out[k] <== a[k] * (b[k]-c[k]) + c[k];
}
}

View File

@@ -1,53 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template H(x) {
signal output out[32];
var c[8] = [0x6a09e667,
0xbb67ae85,
0x3c6ef372,
0xa54ff53a,
0x510e527f,
0x9b05688c,
0x1f83d9ab,
0x5be0cd19];
for (var i=0; i<32; i++) {
out[i] <== (c[x] >> i) & 1;
}
}
template K(x) {
signal output out[32];
var c[64] = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
for (var i=0; i<32; i++) {
out[i] <== (c[x] >> i) & 1;
}
}

View File

@@ -1,35 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "sha256_2.circom";
template Main() {
signal input a;
signal input b;
signal output out;
component sha256_2 = Sha256_2();
sha256_2.a <== a;
sha256_2.b <== a;
out <== sha256_2.out;
}
component main = Main();

View File

@@ -1,45 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/* Maj function for sha256
out = a&b ^ a&c ^ b&c =>
out = a*b + a*c + b*c - 2*a*b*c =>
out = a*( b + c - 2*b*c ) + b*c =>
mid = b*c
out = a*( b + c - 2*mid ) + mid
*/
pragma circom 2.0.0;
template Maj_t(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
signal mid[n];
for (var k=0; k<n; k++) {
mid[k] <== b[k]*c[k];
out[k] <== a[k] * (b[k]+c[k]-2*mid[k]) + mid[k];
}
}

View File

@@ -1,28 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template RotR(n, r) {
signal input in[n];
signal output out[n];
for (var i=0; i<n; i++) {
out[i] <== in[ (i+r)%n ];
}
}

View File

@@ -1,81 +0,0 @@
pragma circom 2.0.0;
include "constants.circom";
include "sha256compression.circom";
template Sha256(nBits) {
signal input in[nBits];
signal output out[256];
var i;
var k;
var nBlocks;
var bitsLastBlock;
nBlocks = ((nBits + 64)\512)+1;
signal paddedIn[nBlocks*512];
for (k=0; k<nBits; k++) {
paddedIn[k] <== in[k];
}
paddedIn[nBits] <== 1;
for (k=nBits+1; k<nBlocks*512-64; k++) {
paddedIn[k] <== 0;
}
for (k = 0; k< 64; k++) {
paddedIn[nBlocks*512 - k -1] <== (nBits >> k)&1;
}
component ha0 = H(0);
component hb0 = H(1);
component hc0 = H(2);
component hd0 = H(3);
component he0 = H(4);
component hf0 = H(5);
component hg0 = H(6);
component hh0 = H(7);
component sha256compression[nBlocks];
for (i=0; i<nBlocks; i++) {
sha256compression[i] = Sha256compression() ;
if (i==0) {
for (k=0; k<32; k++ ) {
sha256compression[i].hin[0*32+k] <== ha0.out[k];
sha256compression[i].hin[1*32+k] <== hb0.out[k];
sha256compression[i].hin[2*32+k] <== hc0.out[k];
sha256compression[i].hin[3*32+k] <== hd0.out[k];
sha256compression[i].hin[4*32+k] <== he0.out[k];
sha256compression[i].hin[5*32+k] <== hf0.out[k];
sha256compression[i].hin[6*32+k] <== hg0.out[k];
sha256compression[i].hin[7*32+k] <== hh0.out[k];
}
} else {
for (k=0; k<32; k++ ) {
sha256compression[i].hin[32*0+k] <== sha256compression[i-1].out[32*0+31-k];
sha256compression[i].hin[32*1+k] <== sha256compression[i-1].out[32*1+31-k];
sha256compression[i].hin[32*2+k] <== sha256compression[i-1].out[32*2+31-k];
sha256compression[i].hin[32*3+k] <== sha256compression[i-1].out[32*3+31-k];
sha256compression[i].hin[32*4+k] <== sha256compression[i-1].out[32*4+31-k];
sha256compression[i].hin[32*5+k] <== sha256compression[i-1].out[32*5+31-k];
sha256compression[i].hin[32*6+k] <== sha256compression[i-1].out[32*6+31-k];
sha256compression[i].hin[32*7+k] <== sha256compression[i-1].out[32*7+31-k];
}
}
for (k=0; k<512; k++) {
sha256compression[i].inp[k] <== paddedIn[i*512+k];
}
}
for (k=0; k<256; k++) {
out[k] <== sha256compression[nBlocks-1].out[k];
}
}

View File

@@ -1,91 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "constants.circom";
include "sha256compression.circom";
include "../bitify.circom";
template Sha256_2() {
signal input a;
signal input b;
signal output out;
var i;
var k;
component bits2num = Bits2Num(216);
component num2bits[2];
num2bits[0] = Num2Bits(216);
num2bits[1] = Num2Bits(216);
num2bits[0].in <== a;
num2bits[1].in <== b;
component sha256compression = Sha256compression() ;
component ha0 = H(0);
component hb0 = H(1);
component hc0 = H(2);
component hd0 = H(3);
component he0 = H(4);
component hf0 = H(5);
component hg0 = H(6);
component hh0 = H(7);
for (k=0; k<32; k++ ) {
sha256compression.hin[0*32+k] <== ha0.out[k];
sha256compression.hin[1*32+k] <== hb0.out[k];
sha256compression.hin[2*32+k] <== hc0.out[k];
sha256compression.hin[3*32+k] <== hd0.out[k];
sha256compression.hin[4*32+k] <== he0.out[k];
sha256compression.hin[5*32+k] <== hf0.out[k];
sha256compression.hin[6*32+k] <== hg0.out[k];
sha256compression.hin[7*32+k] <== hh0.out[k];
}
for (i=0; i<216; i++) {
sha256compression.inp[i] <== num2bits[0].out[215-i];
sha256compression.inp[i+216] <== num2bits[1].out[215-i];
}
sha256compression.inp[432] <== 1;
for (i=433; i<503; i++) {
sha256compression.inp[i] <== 0;
}
sha256compression.inp[503] <== 1;
sha256compression.inp[504] <== 1;
sha256compression.inp[505] <== 0;
sha256compression.inp[506] <== 1;
sha256compression.inp[507] <== 1;
sha256compression.inp[508] <== 0;
sha256compression.inp[509] <== 0;
sha256compression.inp[510] <== 0;
sha256compression.inp[511] <== 0;
for (i=0; i<216; i++) {
bits2num.in[i] <== sha256compression.out[255-i];
}
out <== bits2num.out;
}

View File

@@ -1,166 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "constants.circom";
include "t1.circom";
include "t2.circom";
include "../binsum.circom";
include "sigmaplus.circom";
include "sha256compression_function.circom";
template Sha256compression() {
signal input hin[256];
signal input inp[512];
signal output out[256];
signal a[65][32];
signal b[65][32];
signal c[65][32];
signal d[65][32];
signal e[65][32];
signal f[65][32];
signal g[65][32];
signal h[65][32];
signal w[64][32];
var outCalc[256] = sha256compression(hin, inp);
var i;
for (i=0; i<256; i++) out[i] <-- outCalc[i];
component sigmaPlus[48];
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
component ct_k[64];
for (i=0; i<64; i++) ct_k[i] = K(i);
component t1[64];
for (i=0; i<64; i++) t1[i] = T1();
component t2[64];
for (i=0; i<64; i++) t2[i] = T2();
component suma[64];
for (i=0; i<64; i++) suma[i] = BinSum(32, 2);
component sume[64];
for (i=0; i<64; i++) sume[i] = BinSum(32, 2);
component fsum[8];
for (i=0; i<8; i++) fsum[i] = BinSum(32, 2);
var k;
var t;
for (t=0; t<64; t++) {
if (t<16) {
for (k=0; k<32; k++) {
w[t][k] <== inp[t*32+31-k];
}
} else {
for (k=0; k<32; k++) {
sigmaPlus[t-16].in2[k] <== w[t-2][k];
sigmaPlus[t-16].in7[k] <== w[t-7][k];
sigmaPlus[t-16].in15[k] <== w[t-15][k];
sigmaPlus[t-16].in16[k] <== w[t-16][k];
}
for (k=0; k<32; k++) {
w[t][k] <== sigmaPlus[t-16].out[k];
}
}
}
for (k=0; k<32; k++ ) {
a[0][k] <== hin[k];
b[0][k] <== hin[32*1 + k];
c[0][k] <== hin[32*2 + k];
d[0][k] <== hin[32*3 + k];
e[0][k] <== hin[32*4 + k];
f[0][k] <== hin[32*5 + k];
g[0][k] <== hin[32*6 + k];
h[0][k] <== hin[32*7 + k];
}
for (t = 0; t<64; t++) {
for (k=0; k<32; k++) {
t1[t].h[k] <== h[t][k];
t1[t].e[k] <== e[t][k];
t1[t].f[k] <== f[t][k];
t1[t].g[k] <== g[t][k];
t1[t].k[k] <== ct_k[t].out[k];
t1[t].w[k] <== w[t][k];
t2[t].a[k] <== a[t][k];
t2[t].b[k] <== b[t][k];
t2[t].c[k] <== c[t][k];
}
for (k=0; k<32; k++) {
sume[t].in[0][k] <== d[t][k];
sume[t].in[1][k] <== t1[t].out[k];
suma[t].in[0][k] <== t1[t].out[k];
suma[t].in[1][k] <== t2[t].out[k];
}
for (k=0; k<32; k++) {
h[t+1][k] <== g[t][k];
g[t+1][k] <== f[t][k];
f[t+1][k] <== e[t][k];
e[t+1][k] <== sume[t].out[k];
d[t+1][k] <== c[t][k];
c[t+1][k] <== b[t][k];
b[t+1][k] <== a[t][k];
a[t+1][k] <== suma[t].out[k];
}
}
for (k=0; k<32; k++) {
fsum[0].in[0][k] <== hin[32*0+k];
fsum[0].in[1][k] <== a[64][k];
fsum[1].in[0][k] <== hin[32*1+k];
fsum[1].in[1][k] <== b[64][k];
fsum[2].in[0][k] <== hin[32*2+k];
fsum[2].in[1][k] <== c[64][k];
fsum[3].in[0][k] <== hin[32*3+k];
fsum[3].in[1][k] <== d[64][k];
fsum[4].in[0][k] <== hin[32*4+k];
fsum[4].in[1][k] <== e[64][k];
fsum[5].in[0][k] <== hin[32*5+k];
fsum[5].in[1][k] <== f[64][k];
fsum[6].in[0][k] <== hin[32*6+k];
fsum[6].in[1][k] <== g[64][k];
fsum[7].in[0][k] <== hin[32*7+k];
fsum[7].in[1][k] <== h[64][k];
}
for (k=0; k<32; k++) {
out[31-k] === fsum[0].out[k];
out[32+31-k] === fsum[1].out[k];
out[64+31-k] === fsum[2].out[k];
out[96+31-k] === fsum[3].out[k];
out[128+31-k] === fsum[4].out[k];
out[160+31-k] === fsum[5].out[k];
out[192+31-k] === fsum[6].out[k];
out[224+31-k] === fsum[7].out[k];
}
}

View File

@@ -1,112 +0,0 @@
// signal input hin[256];
// signal input inp[512];
// signal output out[256];
pragma circom 2.0.0;
function rrot(x, n) {
return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF;
}
function bsigma0(x) {
return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22);
}
function bsigma1(x) {
return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25);
}
function ssigma0(x) {
return rrot(x,7) ^ rrot(x,18) ^ (x >> 3);
}
function ssigma1(x) {
return rrot(x,17) ^ rrot(x,19) ^ (x >> 10);
}
function Maj(x, y, z) {
return (x&y) ^ (x&z) ^ (y&z);
}
function Ch(x, y, z) {
return (x & y) ^ ((0xFFFFFFFF ^x) & z);
}
function sha256K(i) {
var k[64] = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
];
return k[i];
}
function sha256compression(hin, inp) {
var H[8];
var a;
var b;
var c;
var d;
var e;
var f;
var g;
var h;
var out[256];
for (var i=0; i<8; i++) {
H[i] = 0;
for (var j=0; j<32; j++) {
H[i] += hin[i*32+j] << j;
}
}
a=H[0];
b=H[1];
c=H[2];
d=H[3];
e=H[4];
f=H[5];
g=H[6];
h=H[7];
var w[64];
var T1;
var T2;
for (var i=0; i<64; i++) {
if (i<16) {
w[i]=0;
for (var j=0; j<32; j++) {
w[i] += inp[i*32+31-j]<<j;
}
} else {
w[i] = (ssigma1(w[i-2]) + w[i-7] + ssigma0(w[i-15]) + w[i-16]) & 0xFFFFFFFF;
}
T1 = (h + bsigma1(e) + Ch(e,f,g) + sha256K(i) + w[i]) & 0xFFFFFFFF;
T2 = (bsigma0(a) + Maj(a,b,c)) & 0xFFFFFFFF;
h=g;
g=f;
f=e;
e=(d+T1) & 0xFFFFFFFF;
d=c;
c=b;
b=a;
a=(T1+T2) & 0xFFFFFFFF;
}
H[0] = H[0] + a;
H[1] = H[1] + b;
H[2] = H[2] + c;
H[3] = H[3] + d;
H[4] = H[4] + e;
H[5] = H[5] + f;
H[6] = H[6] + g;
H[7] = H[7] + h;
for (var i=0; i<8; i++) {
for (var j=0; j<32; j++) {
out[i*32+31-j] = (H[i] >> j) & 1;
}
}
return out;
}

View File

@@ -1,33 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
template ShR(n, r) {
signal input in[n];
signal output out[n];
for (var i=0; i<n; i++) {
if (i+r >= n) {
out[i] <== 0;
} else {
out[i] <== in[ i+r ];
}
}
}

View File

@@ -1,77 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "xor3.circom";
include "rotate.circom";
include "shift.circom";
template SmallSigma(ra, rb, rc) {
signal input in[32];
signal output out[32];
var k;
component rota = RotR(32, ra);
component rotb = RotR(32, rb);
component shrc = ShR(32, rc);
for (k=0; k<32; k++) {
rota.in[k] <== in[k];
rotb.in[k] <== in[k];
shrc.in[k] <== in[k];
}
component xor3 = Xor3(32);
for (k=0; k<32; k++) {
xor3.a[k] <== rota.out[k];
xor3.b[k] <== rotb.out[k];
xor3.c[k] <== shrc.out[k];
}
for (k=0; k<32; k++) {
out[k] <== xor3.out[k];
}
}
template BigSigma(ra, rb, rc) {
signal input in[32];
signal output out[32];
var k;
component rota = RotR(32, ra);
component rotb = RotR(32, rb);
component rotc = RotR(32, rc);
for (k=0; k<32; k++) {
rota.in[k] <== in[k];
rotb.in[k] <== in[k];
rotc.in[k] <== in[k];
}
component xor3 = Xor3(32);
for (k=0; k<32; k++) {
xor3.a[k] <== rota.out[k];
xor3.b[k] <== rotb.out[k];
xor3.c[k] <== rotc.out[k];
}
for (k=0; k<32; k++) {
out[k] <== xor3.out[k];
}
}

View File

@@ -1,50 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "../binsum.circom";
include "sigma.circom";
template SigmaPlus() {
signal input in2[32];
signal input in7[32];
signal input in15[32];
signal input in16[32];
signal output out[32];
var k;
component sigma1 = SmallSigma(17,19,10);
component sigma0 = SmallSigma(7, 18, 3);
for (k=0; k<32; k++) {
sigma1.in[k] <== in2[k];
sigma0.in[k] <== in15[k];
}
component sum = BinSum(32, 4);
for (k=0; k<32; k++) {
sum.in[0][k] <== sigma1.out[k];
sum.in[1][k] <== in7[k];
sum.in[2][k] <== sigma0.out[k];
sum.in[3][k] <== in16[k];
}
for (k=0; k<32; k++) {
out[k] <== sum.out[k];
}
}

View File

@@ -1,58 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "../binsum.circom";
include "sigma.circom";
include "ch.circom";
template T1() {
signal input h[32];
signal input e[32];
signal input f[32];
signal input g[32];
signal input k[32];
signal input w[32];
signal output out[32];
var ki;
component ch = Ch_t(32);
component bigsigma1 = BigSigma(6, 11, 25);
for (ki=0; ki<32; ki++) {
bigsigma1.in[ki] <== e[ki];
ch.a[ki] <== e[ki];
ch.b[ki] <== f[ki];
ch.c[ki] <== g[ki];
}
component sum = BinSum(32, 5);
for (ki=0; ki<32; ki++) {
sum.in[0][ki] <== h[ki];
sum.in[1][ki] <== bigsigma1.out[ki];
sum.in[2][ki] <== ch.out[ki];
sum.in[3][ki] <== k[ki];
sum.in[4][ki] <== w[ki];
}
for (ki=0; ki<32; ki++) {
out[ki] <== sum.out[ki];
}
}

View File

@@ -1,51 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "../binsum.circom";
include "sigma.circom";
include "maj.circom";
template T2() {
signal input a[32];
signal input b[32];
signal input c[32];
signal output out[32];
var k;
component bigsigma0 = BigSigma(2, 13, 22);
component maj = Maj_t(32);
for (k=0; k<32; k++) {
bigsigma0.in[k] <== a[k];
maj.a[k] <== a[k];
maj.b[k] <== b[k];
maj.c[k] <== c[k];
}
component sum = BinSum(32, 2);
for (k=0; k<32; k++) {
sum.in[0][k] <== bigsigma0.out[k];
sum.in[1][k] <== maj.out[k];
}
for (k=0; k<32; k++) {
out[k] <== sum.out[k];
}
}

View File

@@ -1,45 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/* Xor3 function for sha256
out = a ^ b ^ c =>
out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c =>
out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c =>
mid = b*c
out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid
*/
pragma circom 2.0.0;
template Xor3(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
signal mid[n];
for (var k=0; k<n; k++) {
mid[k] <== b[k]*c[k];
out[k] <== a[k] * (1 -2*b[k] -2*c[k] +4*mid[k]) + b[k] + c[k] -2*mid[k];
}
}

View File

@@ -1,36 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "compconstant.circom";
template Sign() {
signal input in[254];
signal output sign;
component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
var i;
for (i=0; i<254; i++) {
comp.in[i] <== in[i];
}
sign <== comp.out;
}

View File

@@ -1,58 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "../mimc.circom";
/*
Hash1 = H(1 | key | value)
*/
template SMTHash1() {
signal input key;
signal input value;
signal output out;
component h = MultiMiMC7(2, 91); // Constant
h.in[0] <== key;
h.in[1] <== value;
h.k <== 1;
out <== h.out;
}
/*
This component is used to create the 2 nodes.
Hash2 = H(Hl | Hr)
*/
template SMTHash2() {
signal input L;
signal input R;
signal output out;
component h = MultiMiMC7(2, 91); // Constant
h.in[0] <== L;
h.in[1] <== R;
h.k <== 0;
out <== h.out;
}

View File

@@ -1,57 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
pragma circom 2.0.0;
include "../poseidon.circom";
/*
Hash1 = H(1 | key | value)
*/
template SMTHash1() {
signal input key;
signal input value;
signal output out;
component h = Poseidon(3); // Constant
h.inputs[0] <== key;
h.inputs[1] <== value;
h.inputs[2] <== 1;
out <== h.out;
}
/*
This component is used to create the 2 nodes.
Hash2 = H(Hl | Hr)
*/
template SMTHash2() {
signal input L;
signal input R;
signal output out;
component h = Poseidon(2); // Constant
h.inputs[0] <== L;
h.inputs[1] <== R;
out <== h.out;
}

View File

@@ -1,103 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
This component finds the level where the oldInsert is done.
The rules are:
levIns[i] == 1 if its level and all the child levels have a sibling of 0 and
the parent level has a sibling != 0. Considere that the root level always has
a parent with a sibling != 0.
┌──────────────┐
│ │
│ │───▶ levIns[0] <== (1-done[i])
│ │
└──────────────┘
done[0]
done[i-1] <== levIns[i] + done[i]
┌───────────┐ ┌──────────────┐
│ │ │ │
sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
│ │ │ │
└───────────┘ └──────────────┘
done[i]
done[n-2] <== levIns[n-1]
┌───────────┐ ┌──────────────┐
│ │ │ │
sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out)
│ │ │ │
└───────────┘ └──────────────┘
┌───────────┐
│ │
sibling[n-1]───▶│IsZero[n-1]│────▶ === 0
│ │
└───────────┘
*/
pragma circom 2.0.0;
template SMTLevIns(nLevels) {
signal input enabled;
signal input siblings[nLevels];
signal output levIns[nLevels];
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
var i;
component isZero[nLevels];
for (i=0; i<nLevels; i++) {
isZero[i] = IsZero();
isZero[i].in <== siblings[i];
}
// The last level must always have a sibling of 0. If not, then it cannot be inserted.
(isZero[nLevels-1].out - 1) * enabled === 0;
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
done[nLevels-2] <== levIns[nLevels-1];
for (i=nLevels-2; i>0; i--) {
levIns[i] <== (1-done[i])*(1-isZero[i-1].out);
done[i-1] <== levIns[i] + done[i];
}
levIns[0] <== (1-done[0]);
}

View File

@@ -1,261 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/***************************************************************************************************
SMTProcessor: Sparse Merkle Tree processor is a component to verify an insert/update/delete elements
into the Sparse Merkle tree.
Insert to an empty leaf
=======================
STATE OLD STATE NEW STATE
===== ========= =========
oldRoot newRoot
▲ ▲
│ │
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
│ │
│ │
┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐
top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│
│ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘
│ │
│ │
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
│ │
│ │
┌────┴────┐ ┌────┴────┐
old0 │ 0 │ │New1Leaf │
└─────────┘ └─────────┘
┏━━━━━━━┓ ┏━━━━━━━┓
na ┃ Hash ┃ ┃ Hash ┃
┗━━━━━━━┛ ┗━━━━━━━┛
┏━━━━━━━┓ ┏━━━━━━━┓
na ┃ Hash ┃ ┃ Hash ┃
┗━━━━━━━┛ ┗━━━━━━━┛
Insert to a used leaf.
=====================
STATE OLD STATE NEW STATE
===== ========= =========
oldRoot newRoot
▲ ▲
│ │
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
│ │
│ │
┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐
top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│
│ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘
│ │
│ │
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
│ │
│ │
┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐
bot │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │
└─────────┘ │ ┗━━━━━━━┛ └───────┘
┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓
bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐
┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │
┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐
bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │
┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘
┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐
new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │
┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘
┏━━━━━━━┓ ┏━━━━━━━┓
na ┃ Hash ┃ ┃ Hash ┃
┗━━━━━━━┛ ┗━━━━━━━┛
┏━━━━━━━┓ ┏━━━━━━━┓
na ┃ Hash ┃ ┃ Hash ┃
┗━━━━━━━┛ ┗━━━━━━━┛
Fnction
fnc[0] fnc[1]
0 0 NOP
0 1 UPDATE
1 0 INSERT
1 1 DELETE
***************************************************************************************************/
pragma circom 2.0.0;
include "../gates.circom";
include "../bitify.circom";
include "../comparators.circom";
include "../switcher.circom";
include "smtlevins.circom";
include "smtprocessorlevel.circom";
include "smtprocessorsm.circom";
include "smthash_poseidon.circom";
template SMTProcessor(nLevels) {
signal input oldRoot;
signal output newRoot;
signal input siblings[nLevels];
signal input oldKey;
signal input oldValue;
signal input isOld0;
signal input newKey;
signal input newValue;
signal input fnc[2];
signal enabled;
var i;
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1];
component hash1Old = SMTHash1();
hash1Old.key <== oldKey;
hash1Old.value <== oldValue;
component hash1New = SMTHash1();
hash1New.key <== newKey;
hash1New.value <== newValue;
component n2bOld = Num2Bits_strict();
component n2bNew = Num2Bits_strict();
n2bOld.in <== oldKey;
n2bNew.in <== newKey;
component smtLevIns = SMTLevIns(nLevels);
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
smtLevIns.enabled <== enabled;
component xors[nLevels];
for (i=0; i<nLevels; i++) {
xors[i] = XOR();
xors[i].a <== n2bOld.out[i];
xors[i].b <== n2bNew.out[i];
}
component sm[nLevels];
for (i=0; i<nLevels; i++) {
sm[i] = SMTProcessorSM();
if (i==0) {
sm[i].prev_top <== enabled;
sm[i].prev_old0 <== 0;
sm[i].prev_bot <== 0;
sm[i].prev_new1 <== 0;
sm[i].prev_na <== 1-enabled;
sm[i].prev_upd <== 0;
} else {
sm[i].prev_top <== sm[i-1].st_top;
sm[i].prev_old0 <== sm[i-1].st_old0;
sm[i].prev_bot <== sm[i-1].st_bot;
sm[i].prev_new1 <== sm[i-1].st_new1;
sm[i].prev_na <== sm[i-1].st_na;
sm[i].prev_upd <== sm[i-1].st_upd;
}
sm[i].is0 <== isOld0;
sm[i].xor <== xors[i].out;
sm[i].fnc[0] <== fnc[0];
sm[i].fnc[1] <== fnc[1];
sm[i].levIns <== smtLevIns.levIns[i];
}
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
component levels[nLevels];
for (i=nLevels-1; i != -1; i--) {
levels[i] = SMTProcessorLevel();
levels[i].st_top <== sm[i].st_top;
levels[i].st_old0 <== sm[i].st_old0;
levels[i].st_bot <== sm[i].st_bot;
levels[i].st_new1 <== sm[i].st_new1;
levels[i].st_na <== sm[i].st_na;
levels[i].st_upd <== sm[i].st_upd;
levels[i].sibling <== siblings[i];
levels[i].old1leaf <== hash1Old.out;
levels[i].new1leaf <== hash1New.out;
levels[i].newlrbit <== n2bNew.out[i];
if (i==nLevels-1) {
levels[i].oldChild <== 0;
levels[i].newChild <== 0;
} else {
levels[i].oldChild <== levels[i+1].oldRoot;
levels[i].newChild <== levels[i+1].newRoot;
}
}
component topSwitcher = Switcher();
topSwitcher.sel <== fnc[0]*fnc[1];
topSwitcher.L <== levels[0].oldRoot;
topSwitcher.R <== levels[0].newRoot;
component checkOldInput = ForceEqualIfEnabled();
checkOldInput.enabled <== enabled;
checkOldInput.in[0] <== oldRoot;
checkOldInput.in[1] <== topSwitcher.outL;
newRoot <== enabled * (topSwitcher.outR - oldRoot) + oldRoot;
// topSwitcher.outL === oldRoot*enabled;
// topSwitcher.outR === newRoot*enabled;
// Ckeck keys are equal if updating
component areKeyEquals = IsEqual();
areKeyEquals.in[0] <== oldKey;
areKeyEquals.in[1] <== newKey;
component keysOk = MultiAND(3);
keysOk.in[0] <== 1-fnc[0];
keysOk.in[1] <== fnc[1];
keysOk.in[2] <== 1-areKeyEquals.out;
keysOk.out === 0;
}

View File

@@ -1,95 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/******
SMTProcessorLevel
This circuit has 2 hash
Outputs according to the state.
State oldRoot newRoot
===== ======= =======
top H'(oldChild, sibling) H'(newChild, sibling)
old0 0 new1leaf
bot old1leaf H'(newChild, 0)
new1 old1leaf H'(new1leaf, old1leaf)
na 0 0
upd old1leaf new1leaf
H' is the Hash function with the inputs shifted acordingly.
*****/
pragma circom 2.0.0;
template SMTProcessorLevel() {
signal input st_top;
signal input st_old0;
signal input st_bot;
signal input st_new1;
signal input st_na;
signal input st_upd;
signal output oldRoot;
signal output newRoot;
signal input sibling;
signal input old1leaf;
signal input new1leaf;
signal input newlrbit;
signal input oldChild;
signal input newChild;
signal aux[4];
component oldProofHash = SMTHash2();
component newProofHash = SMTHash2();
component oldSwitcher = Switcher();
component newSwitcher = Switcher();
// Old side
oldSwitcher.L <== oldChild;
oldSwitcher.R <== sibling;
oldSwitcher.sel <== newlrbit;
oldProofHash.L <== oldSwitcher.outL;
oldProofHash.R <== oldSwitcher.outR;
aux[0] <== old1leaf * (st_bot + st_new1 + st_upd);
oldRoot <== aux[0] + oldProofHash.out * st_top;
// New side
aux[1] <== newChild * ( st_top + st_bot);
newSwitcher.L <== aux[1] + new1leaf*st_new1;
aux[2] <== sibling*st_top;
newSwitcher.R <== aux[2] + old1leaf*st_new1;
newSwitcher.sel <== newlrbit;
newProofHash.L <== newSwitcher.outL;
newProofHash.R <== newSwitcher.outR;
aux[3] <== newProofHash.out * (st_top + st_bot + st_new1);
newRoot <== aux[3] + new1leaf * (st_old0 + st_upd);
}

View File

@@ -1,165 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/***************************************************************************************************
Each level on a SMTProcessor has a state.
The state of the level depends on the state of te botom level and on `xor` and
`is0` signals.
`isOldLev` 1 when is the level where oldLeaf is.
`xor` signal is 0 if the index bit at the current level is the same in the old
and the new index, and 1 if it is different.
`is0` signal, is 1 if we are inserting/deleting in an empty leaf and 0 if we
are inserting/deleting in a leaf that contains an element.
The states are:
top: While the index bits of the old and new insex in the top level is the same, whe are in the top state.
old0: When the we reach insert level, we go to old0 state
if `is0`=1.
btn: Once in insert level and `is0` =0 we go to btn or new1 level if xor=1
new1: This level is reached when xor=1. Here is where we insert/delete the hash of the
old and the new trees with just one element.
na: Not appliable. After processing it, we go to the na level.
Fnction
fnc[0] fnc[1]
0 0 NOP
0 1 UPDATE
1 0 INSERT
1 1 DELETE
###########
# #
┌────────────────────────────▶# upd #─────────────────────┐
│ ## ## │
│ ######### │
levIns=1 │ │
fnc[0]=0 │ │ any
│ │
│ │
│ │
│ ########### │
│ levIns=1 # # │
levIns=0 │ is0=1 ┌────────────▶# old0 #────────┐ │ any
┌─────┐ │ fnc[0]=1│ ## ## │ │ ┌──────┐
│ │ │ │ ######### │ any │ │ │
│ ▼ │ │ │ ▼ ▼ │
│ ########### │ │ ########### │
│ # # ────────────┘ └────────▶# #│
└──# top # # na #
## ## ───────────────────┐ levIns=1 ┌──▶## ##
######### │ is0=0 │ #########
│ │ fnc[0]=1 │
│ │ xor=1 ########### │ any
│ └──────────────────▶# # │
│ # new1 #──┘
│ ## ##
└────────────────────────────────┐ #########
levIns=1 │ ▲
is0=0 │ ┌─────┘
fnc[0]=1 │ ###########│ xor=1
xor=0 │ # #
▼# btn #
## ##
#########◀───────┐
│ │
│ │
└────────────┘
xor=0
***************************************************************************************************/
pragma circom 2.0.0;
template SMTProcessorSM() {
signal input xor;
signal input is0;
signal input levIns;
signal input fnc[2];
signal input prev_top;
signal input prev_old0;
signal input prev_bot;
signal input prev_new1;
signal input prev_na;
signal input prev_upd;
signal output st_top;
signal output st_old0;
signal output st_bot;
signal output st_new1;
signal output st_na;
signal output st_upd;
signal aux1;
signal aux2;
aux1 <== prev_top * levIns;
aux2 <== aux1*fnc[0]; // prev_top * levIns * fnc[0]
// st_top = prev_top*(1-levIns)
// = + prev_top
// - prev_top * levIns = aux1
st_top <== prev_top - aux1;
// st_old0 = prev_top * levIns * is0 * fnc[0]
// = + prev_top * levIns * is0 * fnc[0] = aux2 * is0
st_old0 <== aux2 * is0; // prev_top * levIns * is0 * fnc[0]
// st_new1 = prev_top * levIns * (1-is0)*fnc[0] * xor + prev_bot*xor =
// = + prev_top * levIns * fnc[0] * xor = aux2 * xor
// - prev_top * levIns * is0 * fnc[0] * xor = st_old0 * xor
// + prev_bot * xor = prev_bot * xor
st_new1 <== (aux2 - st_old0 + prev_bot)*xor;
// st_bot = prev_top * levIns * (1-is0)*fnc[0] * (1-xor) + prev_bot*(1-xor);
// = + prev_top * levIns * fnc[0]
// - prev_top * levIns * is0 * fnc[0]
// - prev_top * levIns * fnc[0] * xor
// + prev_top * levIns * is0 * fnc[0] * xor
// + prev_bot
// - prev_bot * xor
st_bot <== (1-xor) * (aux2 - st_old0 + prev_bot);
// st_upd = prev_top * (1-fnc[0]) *levIns;
// = + prev_top * levIns
// - prev_top * levIns * fnc[0]
st_upd <== aux1 - aux2;
// st_na = prev_new1 + prev_old0 + prev_na + prev_upd;
// = + prev_new1
// + prev_old0
// + prev_na
// + prev_upd
st_na <== prev_new1 + prev_old0 + prev_na + prev_upd;
}

View File

@@ -1,138 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
SMTVerifier is a component to verify inclusion/exclusion of an element in the tree
fnc: 0 -> VERIFY INCLUSION
1 -> VERIFY NOT INCLUSION
*/
pragma circom 2.0.0;
include "../gates.circom";
include "../bitify.circom";
include "../comparators.circom";
include "../switcher.circom";
include "smtlevins.circom";
include "smtverifierlevel.circom";
include "smtverifiersm.circom";
include "smthash_poseidon.circom";
template SMTVerifier(nLevels) {
signal input enabled;
signal input root;
signal input siblings[nLevels];
signal input oldKey;
signal input oldValue;
signal input isOld0;
signal input key;
signal input value;
signal input fnc;
var i;
component hash1Old = SMTHash1();
hash1Old.key <== oldKey;
hash1Old.value <== oldValue;
component hash1New = SMTHash1();
hash1New.key <== key;
hash1New.value <== value;
component n2bOld = Num2Bits_strict();
component n2bNew = Num2Bits_strict();
n2bOld.in <== oldKey;
n2bNew.in <== key;
component smtLevIns = SMTLevIns(nLevels);
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
smtLevIns.enabled <== enabled;
component sm[nLevels];
for (i=0; i<nLevels; i++) {
sm[i] = SMTVerifierSM();
if (i==0) {
sm[i].prev_top <== enabled;
sm[i].prev_i0 <== 0;
sm[i].prev_inew <== 0;
sm[i].prev_iold <== 0;
sm[i].prev_na <== 1-enabled;
} else {
sm[i].prev_top <== sm[i-1].st_top;
sm[i].prev_i0 <== sm[i-1].st_i0;
sm[i].prev_inew <== sm[i-1].st_inew;
sm[i].prev_iold <== sm[i-1].st_iold;
sm[i].prev_na <== sm[i-1].st_na;
}
sm[i].is0 <== isOld0;
sm[i].fnc <== fnc;
sm[i].levIns <== smtLevIns.levIns[i];
}
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
component levels[nLevels];
for (i=nLevels-1; i != -1; i--) {
levels[i] = SMTVerifierLevel();
levels[i].st_top <== sm[i].st_top;
levels[i].st_i0 <== sm[i].st_i0;
levels[i].st_inew <== sm[i].st_inew;
levels[i].st_iold <== sm[i].st_iold;
levels[i].st_na <== sm[i].st_na;
levels[i].sibling <== siblings[i];
levels[i].old1leaf <== hash1Old.out;
levels[i].new1leaf <== hash1New.out;
levels[i].lrbit <== n2bNew.out[i];
if (i==nLevels-1) {
levels[i].child <== 0;
} else {
levels[i].child <== levels[i+1].root;
}
}
// Check that if checking for non inclussuin and isOld0==0 then key!=old
component areKeyEquals = IsEqual();
areKeyEquals.in[0] <== oldKey;
areKeyEquals.in[1] <== key;
component keysOk = MultiAND(4);
keysOk.in[0] <== fnc;
keysOk.in[1] <== 1-isOld0;
keysOk.in[2] <== areKeyEquals.out;
keysOk.in[3] <== enabled;
keysOk.out === 0;
// Check the root
component checkRoot = ForceEqualIfEnabled();
checkRoot.enabled <== enabled;
checkRoot.in[0] <== levels[0].root;
checkRoot.in[1] <== root;
// levels[0].root === root;
}

View File

@@ -1,71 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/******
SMTVerifierLevel
This circuit has 1 hash
Outputs according to the state.
State root
===== =======
top H'(child, sibling)
i0 0
iold old1leaf
inew new1leaf
na 0
H' is the Hash function with the inputs shifted acordingly.
*****/
pragma circom 2.0.0;
template SMTVerifierLevel() {
signal input st_top;
signal input st_i0;
signal input st_iold;
signal input st_inew;
signal input st_na;
signal output root;
signal input sibling;
signal input old1leaf;
signal input new1leaf;
signal input lrbit;
signal input child;
signal aux[2];
component proofHash = SMTHash2();
component switcher = Switcher();
switcher.L <== child;
switcher.R <== sibling;
switcher.sel <== lrbit;
proofHash.L <== switcher.outL;
proofHash.R <== switcher.outR;
aux[0] <== proofHash.out * st_top;
aux[1] <== old1leaf*st_iold;
root <== aux[0] + aux[1] + new1leaf*st_inew;
}

View File

@@ -1,106 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
Each level in the SMTVerifier has a state.
This is the state machine.
The signals are
levIns: 1 if we are in the level where the insertion should happen
xor: 1 if the bitKey of the old and new keys are different in this level
is0: Input that indicates that the oldKey is 0
fnc: 0 -> VERIFY INCLUSION
1 -> VERIFY NOT INCLUSION
err state is not a state itself. It's a lack of state.
The end of the last level will have to be `na`
levIns=0 any
┌────┐ ┌────┐
│ │ │ │
│ ▼ levIns=1 ▼ │
│ ########### is0=1 ########### ########### │
│ # # fnc=1 # # any # # │
└──# top # ─────────────────────▶# i0 #───────────────▶# na #──┘
## ## ──────────┐ ## ## ┌───────▶## ##
########─────────────┐│ ######### │┌────────▶#########
││ levIns=1 ││
││ is0=0 ########### ││
││ fnc=1 # # any│
│└──────────▶ # iold #────────┘│
│ ## ## │
│ ######### │
│ │
│ levIns=1 ########### │
│ fnc=0 # # any
└────────────▶# inew #─────────┘
## ##
#########
*/
pragma circom 2.0.0;
template SMTVerifierSM() {
signal input is0;
signal input levIns;
signal input fnc;
signal input prev_top;
signal input prev_i0;
signal input prev_iold;
signal input prev_inew;
signal input prev_na;
signal output st_top;
signal output st_i0;
signal output st_iold;
signal output st_inew;
signal output st_na;
signal prev_top_lev_ins;
signal prev_top_lev_ins_fnc;
prev_top_lev_ins <== prev_top * levIns;
prev_top_lev_ins_fnc <== prev_top_lev_ins*fnc; // prev_top * levIns * fnc
// st_top = prev_top * (1-levIns)
// = + prev_top
// - prev_top * levIns
st_top <== prev_top - prev_top_lev_ins;
// st_inew = prev_top * levIns * (1-fnc)
// = + prev_top * levIns
// - prev_top * levIns * fnc
st_inew <== prev_top_lev_ins - prev_top_lev_ins_fnc;
// st_iold = prev_top * levIns * (1-is0)*fnc
// = + prev_top * levIns * fnc
// - prev_top * levIns * fnc * is0
st_iold <== prev_top_lev_ins_fnc * (1 - is0);
// st_i0 = prev_top * levIns * is0
// = + prev_top * levIns * is0
st_i0 <== prev_top_lev_ins * is0;
st_na <== prev_na + prev_inew + prev_iold + prev_i0;
}

View File

@@ -1,42 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
Assume sel is binary.
If sel == 0 then outL = L and outR=R
If sel == 1 then outL = R and outR=L
*/
pragma circom 2.0.0;
template Switcher() {
signal input sel;
signal input L;
signal input R;
signal output outL;
signal output outR;
signal aux;
aux <== (R-L)*sel; // We create aux in order to have only one multiplication
outL <== aux + L;
outR <== -aux + R;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,2 +0,0 @@

View File

@@ -1,33 +0,0 @@
{
"name": "circomlib",
"version": "2.0.5",
"description": "Basic circuits library for Circom",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "mocha --max-old-space-size=4000"
},
"keywords": [
"pedersen",
"hash",
"ethereum",
"circuit",
"circom",
"zksnark"
],
"repository": {
"type": "git",
"url": "https://github.com/iden3/circomlib.git"
},
"author": "0Kims",
"license": "GPL-3.0",
"devDependencies": {
"blake-hash": "^2.0.0",
"chai": "^4.3.4",
"circom_tester": "0.0.13",
"circomlibjs": "^0.1.4",
"mocha": "^9.1.3"
}
}

View File

@@ -1,77 +0,0 @@
const chai = require("chai");
const path = require("path");
const assert = chai.assert;
const Scalar = require("ffjavascript").Scalar;
const F1Field = require("ffjavascript").F1Field;
const utils = require("ffjavascript").utils;
const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const F = new F1Field(q);
const wasm_tester = require("circom_tester").wasm;
function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
}
function getBits(v, n) {
const res = [];
for (let i=0; i<n; i++) {
if (Scalar.isOdd(Scalar.shr(v,i))) {
res.push(F.one);
} else {
res.push(F.zero);
}
}
return res;
}
describe("Aliascheck test", function () {
this.timeout(100000);
let cir;
before( async() => {
cir = await wasm_tester(path.join(__dirname, "circuits", "aliascheck_test.circom"));
});
it("Satisfy the aliastest 0", async () => {
const inp = getBits(0, 254);
await cir.calculateWitness({in: inp}, true);
});
it("Satisfy the aliastest 3", async () => {
const inp = getBits(3, 254);
await cir.calculateWitness({in: inp}, true);
});
it("Satisfy the aliastest q-1", async () => {
const inp = getBits(F.e(-1), 254);
// console.log(JSON.stringify(utils.stringifyBigInts(inp)));
await cir.calculateWitness({in: inp}, true);
});
it("Should not satisfy an input of q", async () => {
const inp = getBits(q, 254);
try {
await cir.calculateWitness({in: inp}, true);
assert(false);
} catch(err) {
assert(err.message.includes("Assert Failed"));
}
});
it("Should not satisfy all ones", async () => {
const inp = getBits(Scalar.sub(Scalar.shl(1, 254) , 1) , 254);
try {
await cir.calculateWitness({in: inp}, true);
assert(false);
} catch(err) {
assert(err.message.includes("Assert Failed"));
}
});
});

View File

@@ -1,118 +0,0 @@
const chai = require("chai");
const path = require("path");
const createBlakeHash = require("blake-hash");
const buildEddsa = require("circomlibjs").buildEddsa;
const assert = chai.assert;
const wasm_tester = require("circom_tester").wasm;
const utils = require("ffjavascript").utils;
const Scalar = require("ffjavascript").Scalar;
describe("Baby Jub test", function () {
let eddsa;
let F;
let circuitAdd;
let circuitTest;
let circuitPbk;
this.timeout(100000);
before( async() => {
eddsa = await buildEddsa();
F = eddsa.F;
circuitAdd = await wasm_tester(path.join(__dirname, "circuits", "babyadd_tester.circom"));
circuitTest = await wasm_tester(path.join(__dirname, "circuits", "babycheck_test.circom"));
circuitPbk = await wasm_tester(path.join(__dirname, "circuits", "babypbk_test.circom"));
});
it("Should add point (0,1) and (0,1)", async () => {
const input={
x1: 0,
y1: 1,
x2: 0,
y2: 1
};
const w = await circuitAdd.calculateWitness(input, true);
await circuitAdd.assertOut(w, {xout: 0, yout: 1});
});
it("Should add 2 same numbers", async () => {
const input={
x1: 17777552123799933955779906779655732241715742912184938656739573121738514868268n,
y1: 2626589144620713026669568689430873010625803728049924121243784502389097019475n,
x2: 17777552123799933955779906779655732241715742912184938656739573121738514868268n,
y2: 2626589144620713026669568689430873010625803728049924121243784502389097019475n
};
const w = await circuitAdd.calculateWitness(input, true);
await circuitAdd.assertOut(w, {
xout: 6890855772600357754907169075114257697580319025794532037257385534741338397365n,
yout: 4338620300185947561074059802482547481416142213883829469920100239455078257889n
});
});
it("Should add 2 different numbers", async () => {
const input={
x1: 17777552123799933955779906779655732241715742912184938656739573121738514868268n,
y1: 2626589144620713026669568689430873010625803728049924121243784502389097019475n,
x2: 16540640123574156134436876038791482806971768689494387082833631921987005038935n,
y2: 20819045374670962167435360035096875258406992893633759881276124905556507972311n
};
const w = await circuitAdd.calculateWitness(input, true);
await circuitAdd.assertOut(w, {
xout: 7916061937171219682591368294088513039687205273691143098332585753343424131937n,
yout: 14035240266687799601661095864649209771790948434046947201833777492504781204499n
});
});
it("Should check (0,1) is a valid point", async() => {
const w = await circuitTest.calculateWitness({x: 0, y:1}, true);
await circuitTest.checkConstraints(w);
});
it("Should check (1,0) is an invalid point", async() => {
try {
await circuitTest.calculateWitness({x: 1, y: 0}, true);
assert(false, "Should be a valid point");
} catch(err) {
assert(err.message.includes("Assert Failed"));
}
});
it("Should extract the public key from the private one", async () => {
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
const S = Scalar.shr(utils.leBuff2int(pvk), 3);
const A = eddsa.prv2pub(rawpvk);
const input = {
in : S
};
const w = await circuitPbk.calculateWitness(input, true);
await circuitPbk.assertOut(w, {Ax : F.toObject(A[0]), Ay: F.toObject(A[1])});
await circuitPbk.checkConstraints(w);
});
});

View File

@@ -1,52 +0,0 @@
const path = require("path");
const Scalar = require("ffjavascript").Scalar;
const wasm_tester = require("circom_tester").wasm;
function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
}
async function checkSub(_a,_b, circuit) {
let a=Scalar.e(_a);
let b=Scalar.e(_b);
if (Scalar.lt(a, 0)) a = Scalar.add(a, Scalar.shl(1, 16));
if (Scalar.lt(b, 0)) b = Scalar.add(b, Scalar.shl(1, 16));
const w = await circuit.calculateWitness({a: a, b: b}, true);
let res = Scalar.sub(a, b);
if (Scalar.lt(res, 0)) res = Scalar.add(res, Scalar.shl(1, 16));
await circuit.assertOut(w, {out: res});
}
describe("BinSub test", function () {
this.timeout(100000);
let circuit;
before( async() => {
circuit = await wasm_tester(path.join(__dirname, "circuits", "binsub_test.circom"));
});
it("Should check variuos ege cases", async () => {
await checkSub(0,0, circuit);
await checkSub(1,0, circuit);
await checkSub(-1,0, circuit);
await checkSub(2,1, circuit);
await checkSub(2,2, circuit);
await checkSub(2,3, circuit);
await checkSub(2,-1, circuit);
await checkSub(2,-2, circuit);
await checkSub(2,-3, circuit);
await checkSub(-2,-3, circuit);
await checkSub(-2,-2, circuit);
await checkSub(-2,-1, circuit);
await checkSub(-2,0, circuit);
await checkSub(-2,1, circuit);
await checkSub(-2,2, circuit);
await checkSub(-2,3, circuit);
});
});

View File

@@ -1,38 +0,0 @@
const chai = require("chai");
const path = require("path");
const wasm_tester = require("circom_tester").wasm;
const F1Field = require("ffjavascript").F1Field;
const Scalar = require("ffjavascript").Scalar;
exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const Fr = new F1Field(exports.p);
const assert = chai.assert;
describe("Binary sum test", function () {
this.timeout(100000000);
it("Should create a constant circuit", async () => {
const circuit = await wasm_tester(path.join(__dirname, "circuits", "constants_test.circom"));
await circuit.loadConstraints();
assert.equal(circuit.nVars, 2);
assert.equal(circuit.constraints.length, 1);
const witness = await circuit.calculateWitness({ "in": Fr.toString(Fr.e("0xd807aa98"))}, true);
assert(Fr.eq(Fr.e(witness[0]),Fr.e(1)));
assert(Fr.eq(Fr.e(witness[1]),Fr.e("0xd807aa98")));
});
it("Should create a sum circuit", async () => {
const circuit = await wasm_tester(path.join(__dirname, "circuits", "sum_test.circom"));
await circuit.loadConstraints();
assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true);
assert(Fr.eq(Fr.e(witness[0]),Fr.e(1)));
assert(Fr.eq(Fr.e(witness[1]),Fr.e("333")));
});
});

View File

@@ -1,4 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/aliascheck.circom";
component main = AliasCheck();

View File

@@ -1,4 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/babyjub.circom";
component main = BabyAdd();

View File

@@ -1,4 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/babyjub.circom";
component main = BabyCheck();

View File

@@ -1,4 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/babyjub.circom";
component main = BabyPbk();

View File

@@ -1,33 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/bitify.circom";
include "../../circuits/binsub.circom";
template A() {
signal input a; //private
signal input b;
signal output out;
var i;
component n2ba = Num2Bits(16);
component n2bb = Num2Bits(16);
component sub = BinSub(16);
component b2n = Bits2Num(16);
n2ba.in <== a;
n2bb.in <== b;
for (i=0; i<16; i++) {
sub.in[0][i] <== n2ba.out[i];
sub.in[1][i] <== n2bb.out[i];
}
for (i=0; i<16; i++) {
b2n.in[i] <== sub.out[i];
}
out <== b2n.out;
}
component main = A();

View File

@@ -1,20 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/sha256/constants.circom";
template A() {
signal input in;
component h0;
h0 = K(8);
var lc = 0;
var e = 1;
for (var i=0; i<32; i++) {
lc = lc + e*h0.out[i];
e *= 2;
}
lc === in;
}
component main {public [in]} = A();

View File

@@ -1,5 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/eddsa.circom";
component main = EdDSAVerifier(80);

View File

@@ -1,5 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/eddsamimc.circom";
component main = EdDSAMiMCVerifier();

View File

@@ -1,5 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/eddsaposeidon.circom";
component main = EdDSAPoseidonVerifier();

View File

@@ -1,5 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/montgomery.circom";
component main = Edwards2Montgomery();

View File

@@ -1,27 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmul.circom";
template Main() {
signal input in[256];
signal output out[2];
var i;
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203];
component escalarMul = EscalarMul(256, base);
escalarMul.inp[0] <== 0;
escalarMul.inp[1] <== 1;
for (i=0; i<256; i++) {
in[i] ==> escalarMul.in[i];
}
escalarMul.out[0] ==> out[0];
escalarMul.out[1] ==> out[1];
}
component main = Main();

View File

@@ -1,33 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmul.circom";
include "../../circuits/bitify.circom";
template Main() {
signal input in;
signal output out[2];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
component n2b = Num2Bits(253);
component escalarMul = EscalarMul(253, base);
escalarMul.inp[0] <== 0;
escalarMul.inp[1] <== 1;
var i;
in ==> n2b.in;
for (i=0; i<253; i++) {
n2b.out[i] ==> escalarMul.in[i];
}
escalarMul.out[0] ==> out[0];
escalarMul.out[1] ==> out[1];
}
component main = Main();

View File

@@ -1,28 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmul.circom";
template Main() {
signal input in[256];
signal output out[2];
var i;
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
component escalarMul = EscalarMul(256, base);
escalarMul.inp[0] <== 0;
escalarMul.inp[1] <== 1;
for (i=0; i<256; i++) {
in[i] ==> escalarMul.in[i];
}
escalarMul.out[0] ==> out[0];
escalarMul.out[1] ==> out[1];
}
component main = Main();

View File

@@ -1,30 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmulany.circom";
include "../../circuits/bitify.circom";
template Main() {
signal input e;
signal input p[2];
signal output out[2];
component n2b = Num2Bits(253);
component escalarMulAny = EscalarMulAny(253);
escalarMulAny.p[0] <== p[0];
escalarMulAny.p[1] <== p[1];
var i;
e ==> n2b.in;
for (i=0; i<253; i++) {
n2b.out[i] ==> escalarMulAny.e[i];
}
escalarMulAny.out[0] ==> out[0];
escalarMulAny.out[1] ==> out[1];
}
component main = Main();

View File

@@ -1,31 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmulfix.circom";
include "../../circuits/bitify.circom";
template Main() {
signal input e;
signal output out[2];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
component n2b = Num2Bits(253);
component escalarMul = EscalarMulFix(253, base);
var i;
e ==> n2b.in;
for (i=0; i<253; i++) {
n2b.out[i] ==> escalarMul.e[i];
}
escalarMul.out[0] ==> out[0];
escalarMul.out[1] ==> out[1];
}
component main = Main();

View File

@@ -1,20 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmulw4table.circom";
template Main() {
signal output out[16][2];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
var escalarMul[16][2] = EscalarMulW4Table(base, 0);
for (var i=0; i<16; i++) {
out[i][0] <== escalarMul[i][0];
out[i][1] <== escalarMul[i][1];
}
}
component main = Main();

View File

@@ -1,19 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmulw4table.circom";
template Main() {
signal input in;
signal output out[16][2];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
var escalarMul[16][2] = EscalarMulW4Table(base, 0);
for (var i=0; i<16; i++) {
out[i][0] <== escalarMul[i][0]*in;
out[i][1] <== escalarMul[i][1]*in;
}
}
component main = Main();

View File

@@ -1,19 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/escalarmulw4table.circom";
template Main() {
signal input in;
signal output out[16][2];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
var escalarMul[16][2] = EscalarMulW4Table(base, 3);
for (var i=0; i<16; i++) {
out[i][0] <== escalarMul[i][0]*in;
out[i][1] <== escalarMul[i][1]*in;
}
}
component main = Main();

View File

@@ -1,5 +0,0 @@
pragma circom 2.0.0;
include "../../circuits/comparators.circom";
component main = GreaterEqThan(32);

Some files were not shown because too many files have changed in this diff Show More