-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
huuuge refactor, more content, better tests
- Loading branch information
Showing
36 changed files
with
2,677 additions
and
1,184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
node_modules | ||
circuits/test | ||
circuits/main | ||
build | ||
build | ||
.yarn |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,17 @@ | ||
{ | ||
// https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/images/fileIcons.png | ||
"material-icon-theme.files.associations": { | ||
"*.circom": "Verilog" | ||
}, | ||
// https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/images/folderIcons.png | ||
"material-icon-theme.folders.associations": { | ||
"circuits": "App", | ||
"inputs": "Json", | ||
"book": "Docs" | ||
"book": "Docs", | ||
"arrays": "Constant", | ||
"basics": "Resolver", | ||
"control-flow": "Routes", | ||
"comparators": "Benchmark", | ||
"bits": "Base" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nodeLinker: node-modules |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,25 @@ | ||
# Circom 101 | ||
# About this Book | ||
|
||
Zero-knowledge proofs are a fascinating area of cryptography that allows parties to prove a statement without revealing any extra information about it; just proving that statement alone. In other words, zero-knowledge proofs can demonstrate that something is true, without revealing what makes that "something" true. | ||
Zero-knowledge cryptography is a fascinating area, where a party can prove a statement without revealing any extra information about it; proving that something is true without revealing what makes that "something" true. | ||
|
||
There are great resources online to learn more about them, to name a few: | ||
Circom is a hardware description language (HDL) specifically designed for creating zero-knowledge proofs. It enables developers to create arithmetic circuits, which are then used to generate proofs that demonstrate a certain statement is true, without revealing any additional information about the inputs used to make that statement. Circom has opened up new possibilities for creating privacy-preserving applications, such as digital identities, voting systems, and financial transactions, where proving the validity of a statement is necessary, but keeping the underlying data private is critical. | ||
|
||
- todo | ||
- todo | ||
- todo | ||
## Resources | ||
|
||
--- | ||
There are many resources about Circom & ZK out there, to list a few: | ||
|
||
Circom is a hardware description language (HDL) specifically designed for creating zero-knowledge proofs. It enables developers to create arithmetic circuits, which are then used to generate proofs that demonstrate a certain statement is true, without revealing any additional information about the inputs used to make that statement. Circom has opened up new possibilities for creating privacy-preserving applications, such as digital identities, voting systems, and financial transactions, where proving the validity of a statement is necessary, but keeping the underlying data private is critical. | ||
- [Official Circom Docs](https://docs.circom.io/) by [@iden3](https://twitter.com/identhree). | ||
- [Circomlib](https://github.com/iden3/circomlib/) is a collection of common circuits, by [@iden3](https://twitter.com/identhree). | ||
- [Circom Tutorial](https://www.rareskills.io/post/circom-tutorial) by [RareSkills](https://twitter.com/RareSkills_io). | ||
- [zkJargon Decoder](https://nmohnblatt.github.io/zk-jargon-decoder/foreword.html) by [@nico_mnbl](https://twitter.com/nico_mnbl). | ||
- [BattleZips](https://battlezips.gitbook.io/battlezips/) by [BattleZips](https://github.com/BattleZips) | ||
|
||
## Tests | ||
|
||
We provide tests via [Circomkit](https://github.com/erhant/circomkit) that demonstrate each circuit described here. In the repository, you can run: | ||
|
||
Although there are quite a lot of implementations of Circom online, I feel like there is a lack of documentation and explanation. For this reason, I have created this book, where we examine circuits and explain how they do what they do. | ||
```sh | ||
yarn test | ||
``` | ||
|
||
> Throughout this book, we always try to make use of `in` and `out` signal naming convention if the circuit permits. | ||
to run all tests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
# Magic Square | ||
# `MagicSquare` | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,104 @@ | ||
# Logic Gates | ||
|
||
TODO | ||
It is often required to do some logical operations like `AND`, `OR`, `NOT` and `XOR` within a circuit. For the circuits within this chapter, we can assume that the inputs are asserted to be bits, i.e. they are either 0 or 1. | ||
|
||
## `AND` | ||
|
||
```cs | ||
template AND() { | ||
signal input in[2]; | ||
signal output out; | ||
|
||
out <== in[0]*in[1]; | ||
} | ||
``` | ||
|
||
The logic table of `AND` is as follows: | ||
|
||
| $\land$ | 0 | 1 | | ||
| ------- | --- | --- | | ||
| 0 | 0 | 0 | | ||
| 1 | 0 | 1 | | ||
|
||
This can be achieved by simply multiplying the two inputs! | ||
|
||
## `OR` | ||
|
||
```cs | ||
template OR() { | ||
signal input in[2]; | ||
signal output out; | ||
|
||
out <== in[0] + in[1] - in[0]*in[1]; | ||
} | ||
``` | ||
|
||
The logic table of `OR` is as follows: | ||
|
||
| $\lor$ | 0 | 1 | | ||
| ------ | --- | --- | | ||
| 0 | 0 | 1 | | ||
| 1 | 1 | 1 | | ||
|
||
We _almost_ achieve the result by adding the two numbers, except that we get 2 when both are 1. Well, `AND` is only 1 when both numbers are 1, so we subtract it from the result to solve that issue. | ||
|
||
What we have is equivalent to `in[0] + in[1] - AND(in)`. | ||
|
||
## `XOR` | ||
|
||
```cs | ||
template XOR() { | ||
signal input in[2]; | ||
signal output out; | ||
|
||
out <== in[0] + in[1] - 2*in[0]*in[1]; | ||
} | ||
``` | ||
|
||
The logic table of `XOR` is as follows: | ||
|
||
| $\oplus$ | 0 | 1 | | ||
| -------- | --- | --- | | ||
| 0 | 0 | 1 | | ||
| 1 | 1 | 0 | | ||
|
||
We can use the same trick for `OR`, just once more, to make the `1 + 1` turn to a zero. What we have is equivalent to `in[0] + in[1] - 2 * AND(in)`. | ||
|
||
## `NOT` | ||
|
||
```cs | ||
template NOT() { | ||
signal input in; | ||
signal output out; | ||
|
||
out <== 1 - in; | ||
} | ||
``` | ||
|
||
A `NOT` gate maps 0 to 1, and 1 to 0. We can achieve this by simply subtracting the signal from 1. Since $1 - 0 = 1$ and $1 - 1 = 0$. | ||
|
||
## `NAND` | ||
|
||
```cs | ||
template NAND() { | ||
signal input in[2]; | ||
signal output out; | ||
|
||
out <== 1 - in[0]*in[1]; | ||
} | ||
``` | ||
|
||
`NAND` is equivalent to `NOT(AND(in))`, giving us the circuit above. | ||
|
||
## `NOR` | ||
|
||
```cs | ||
template NOR() { | ||
signal input in[2]; | ||
signal output out; | ||
|
||
out <== 1 - (in[0] + in[1] - in[0]*in[1]); | ||
} | ||
``` | ||
|
||
`NOR` is equivalent to `NOT(OR(in))`, giving us the circuit above. |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Control Flow | ||
|
||
In the world of arithmetic circuits, control flow is a bit different than what most developers are used to. In normal programming, only one of the branches are executed: | ||
|
||
```c | ||
if (cond) { | ||
foo(); // only if cond == true | ||
} else { | ||
bar(); // only if cond == false | ||
} | ||
``` | ||
|
||
That is not how things work in our circuits! Instead, both branches are executed but only one of them is "returned". | ||
|
||
To understand why, first remind yourself that we are ALWAYS working with integers in our circuits. Both `foo()` and `bar()` will return an integer, and `cond` is either 0 or 1. The trick is to combine these results with `cond` and `NOT(cond)` in a simple sum expression: | ||
|
||
```c | ||
cond*foo() + NOT(cond)*bar(); | ||
``` | ||
Opening this up, we have: | ||
```c | ||
cond*foo() + (1-cond)*bar(); | ||
``` | ||
|
||
In fact, we can use one multiplication instead of two, using the following form: | ||
|
||
```c | ||
cond*(foo() - bar()) + bar(); | ||
``` | ||
|
||
## `IfElse` | ||
|
||
```cs | ||
template IfElse() { | ||
signal input cond; | ||
signal input ifTrue; | ||
signal input ifFalse; | ||
signal output out; | ||
|
||
out <== cond * (ifTrue - ifFalse) + ifFalse; | ||
} | ||
``` | ||
|
||
Following our description above, an `if-else` is defined by the given circuit. Remember that both `ifTrue` and `ifFalse` signals are computed, regardless of the condition, but only one of them is returned. | ||
|
||
### Conditional Constraints | ||
|
||
In your application, there may be cases where `ifTrue` and `ifFalse` can't be valid at the same time, due to some condition; `ifTrue` might constrain a signal to be 0 but `ifFalse` might constrain that same signal to something else. | ||
|
||
In these cases, we may add an auxillary signal which can enable/disable a constraint check. As an example, imagine the following template that constraints a signal to be 5: | ||
|
||
```cs | ||
template IsFive() { | ||
signal input in; | ||
|
||
in - 5 === 0; | ||
} | ||
``` | ||
|
||
We can add an auxillary `isEnabled` signal that is either 0 or 1, and disable this circuit when `isEnabled = 0` as follows: | ||
|
||
```cs | ||
template IsFive() { | ||
signal input in; | ||
signal input isEnabled; | ||
|
||
isEnabled * (in - 5) === 0; | ||
} | ||
``` | ||
|
||
If `isEnabled = 1` both circuits are equivalent, but if `isEnabled = 0` this circuit will always have `0 === 0` regardless of the `in` signal. | ||
|
||
## `Switch` | ||
|
||
```cs | ||
template Switch() { | ||
signal input cond; | ||
signal input in[2]; | ||
signal output out[2]; | ||
|
||
out[0] <== cond * (in[1] - in[0]) + in[0]; | ||
out[1] <== cond * (in[0] - in[1]) + in[1]; | ||
} | ||
``` | ||
|
||
It is often useful to switch the places of two signals based on a condition, which can be achieved with two `IfElse` lines together. |
File renamed without changes.
Oops, something went wrong.