diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7f27970
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# slides
+
+- [RSA and Homomorphic Multiplication](https://github.com/arnaucube/slides/blob/master/rsa-and-homomorphicmultiplication.pdf)
+- [Shamir's Secret Sharing](https://github.com/arnaucube/slides/blob/master/rsa-and-homomorphicmultiplication.pdf)
+- [zkSNARKs from scratch, a technical explanation](https://github.com/arnaucube/slides/blob/master/zksnarks-from-scratch-a-technical-explanation.pdf)
+
+Any error, typo, mistake, etc, open an issue or a pull request and I'll be glad to fix it.
diff --git a/rsa-and-homomorphicmultiplication.pdf b/rsa-and-homomorphicmultiplication.pdf
new file mode 100644
index 0000000..b0e367b
Binary files /dev/null and b/rsa-and-homomorphicmultiplication.pdf differ
diff --git a/shamirsecretsharing.pdf b/shamirsecretsharing.pdf
new file mode 100644
index 0000000..401c2f5
Binary files /dev/null and b/shamirsecretsharing.pdf differ
diff --git a/src/rsa-and-homomorphicmultiplication/rsa-and-homomorphicmultiplication.md b/src/rsa-and-homomorphicmultiplication/rsa-and-homomorphicmultiplication.md
new file mode 100644
index 0000000..281bc0b
--- /dev/null
+++ b/src/rsa-and-homomorphicmultiplication/rsa-and-homomorphicmultiplication.md
@@ -0,0 +1,358 @@
+# RSA and Homomorphic Multiplication
+
+
+
+
+- https://arnaucube.com
+- https://github.com/arnaucube
+- https://twitter.com/arnaucube
+
+
+
+
+ 2018-11-30
+
+
+---
+
+- Intro
+- Public key cryptography
+- Basics of modular arithmetic
+- Brief history of RSA
+- Keys generation
+- Prime numbers
+- Encryption
+- Decryption
+- What's going on in encryption and decryption?
+- Signature
+- Verification of the signature
+- Homomorphic Multiplication with RSA
+- Resources
+
+---
+# Intro
+- I'm not an expert on the field, neither a mathematician. Just an engineer with interest for cryptography
+- Short talk (15 min), with the objective to make a practical introduction to the RSA cryptosystem
+- Is not a talk about mathematical demostrations, is a talk with the objective to get the basic notions to be able to do a practical implementation of the algorithm
+- After the talk, we will do a practical workshop to implement the concepts. We can offer support for Go, Rust, Python and Nodejs (you can choose any other language, but we will not be able to help)
+
+---
+# Public key cryptography
+![pubkencr](https://upload.wikimedia.org/wikipedia/commons/f/f9/Public_key_encryption.svg "pubkencr")
+
+---
+Some examples:
+- RSA
+- Paillier
+- ECC (Corba el·líptica)
+
+---
+# Basics of modular arithmetic
+- Modulus, `mod`, `%`
+- Remainder after division of two numbers
+
+![clocks](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Clock_group.svg/220px-Clock_group.svg.png "clocks")
+
+```
+5 mod 12 = 5
+14 mod 12 = 2
+83 mod 10 = 3
+```
+
+```
+5 + 3 mod 6 = 8 mod 6 = 2
+```
+
+---
+
+# Brief history of RSA
+- RSA (Rivest–Shamir–Adleman): Ron Rivest, Adi Shamir, Leonard Adleman
+- year 1977
+- one of the first public key cryptosystems
+- based on the difficulty of factorization of the product of two big prime numbers
+
+---
+# Prime numbers
+- We need an asymmetric key, in a way where we can decrypt a message encrypted with the asymetric key
+- Without allowing to find the private key from the public key
+- in RSA we resolve this with factorization of prime numbers
+- using prime numbers for $p$ and $q$, it's difficult factorize $n$ to obtain $p$ and $q$, where $n=p*q$
+
+---
+
+Example:
+If we know $n$ which we need to find the $p$ and $q$ values where $p*q=n$:
+```
+n = 35
+```
+To obtain the possible factors, is needed to brute force trying different combinations, until we find:
+```
+p = 5
+q = 7
+```
+In this case is easy as it's a simple example with small numbers. The idea is to do this with big prime numbers
+
+---
+
+Another exmample with more bigger prime numbers:
+```
+n = 272604817800326282194810623604278579733
+```
+From $n$, I don't have a 'direct' way to obtain $p$ and $q$. I need to try by brute force the different values until finding a correct combination.
+```
+p = 17975460804519255043
+q = 15165386899666573831
+n = 17975460804519255043 * 15165386899666573831 = 272604817800326282194810623604278579733
+```
+
+---
+
+If we do this with non prime numbers:
+```
+n = 32
+We can factorize 32 = 2 * 2 * 2 * 2 * 2
+combining that values in two values X * Y
+for example (2*2*2) * (2*2) = 8*4 = 32
+we can also take 2 * (2*2*2*2) = 2 * 16 = 32
+...
+```
+
+---
+
+One example with bigger non prime numbers:
+```
+n = 272604817800326282227951471308464408608
+We can take:
+p = 17975460804519255044
+q = 15165386899666573832
+
+Or also:
+p = 2
+q = 136302408900163141113975735654232204304
+...
+```
+
+In the real world:
+- https://en.wikipedia.org/wiki/RSA_numbers
+- https://en.wikipedia.org/wiki/RSA_Factoring_Challenge#The_prizes_and_records
+
+So, we are basing this in the fact that is not easy to factorize big numbers composed by big primes.
+
+
+---
+# Keys generation
+- PubK: $e$, $n$
+- PrivK: $d$, $n$
+- are choosen randomly 2 big prime numbers $p$ and $q$, that will be secrets
+- $n = p * q$
+- $λ$ is the Carmichael function
+ - $λ(n) = (p − 1) * (q − 1)$
+- Choose a prime number $e$ that satisfies $1 < e < λ(n)$ and $gcd(e, λ(n))=1$
+ - Usually in examples is used $e = 2^16 + 1 = 65537$
+- $d$ such as $e * d = 1 mod λ(n)$
+ - $d = e^(-1) mod λ(n) = e modinv λ(n)$
+
+---
+
+### Example
+- `p = 3`
+- `q = 11`
+- `e = 7` value choosen between 1 and λ(n)=20, where λ(n) is not divisible by this value
+- `n = 3 * 11 = 33`
+- `λ(n) = (3-1) * (11-1) = 2 * 10 = 20`
+- `d` such as `7 * d = 1 mod 20`
+- `d = 3`
+- PubK: `e=7, n=33`
+- PrivK: `d=3, n=33`
+
+---
+
+### Naive code
+```python
+def egcd(a, b):
+ if a == 0:
+ return (b, 0, 1)
+ g, y, x = egcd(b%a,a)
+ return (g, x - (b//a) * y, y)
+
+def modinv(a, m):
+ g, x, y = egcd(a, m)
+ if g != 1:
+ raise Exception('No modular inverse')
+ return x%m
+```
+
+---
+
+```
+def newKeys():
+ p = number.getPrime(n_length)
+ q = number.getPrime(n_length)
+
+ # pubK e, n
+ e = 65537
+ n = p*q
+ pubK = PubK(e, n)
+
+ # privK d, n
+ phi = (p-1) * (q-1)
+ d = modinv(e, phi)
+ privK = PrivK(d, n)
+
+ return({'pubK': pubK, 'privK': privK})
+```
+
+---
+
+# Encryption
+- Brenna wants to send the message `m` to Alice, so, will use the Public Key from Alice to encrypt `m`
+- `m` powered at `e` of the public key from Alice
+- evaluate at modulus of `n`
+
+### Example
+- message to encrypt `m = 5`
+- receiver public key: `e=7, n=33`
+- `c = 5 ^ 7 mod 33 = 78125 mod 33 = 14`
+
+### Naive code
+```python
+def encrypt(pubK, m):
+ c = (m ** pubK.e) % pubK.n
+ return c
+```
+
+---
+# Decrypt
+- from an encrypted value `c`
+- `c` powered at `d` of the private key of the person to who the message was encrypted
+- evaluate at modulus of `n`
+
+### Example
+- receiver private key, PrivK: `d=3, n=33`
+- `m = 14 ^ 3 mod 33 = 2744 mod 33 = 5`
+
+### Naive code
+```python
+def decrypt(privK, c):
+ m_d = (c ** privK.d) % privK.n
+ return m_d
+```
+
+---
+# What's going on when encrypting and decrypting?
+
+![encrdecr](https://cdn-images-1.medium.com/max/1600/1*4AXQNOrddQJud0fZJ3FNgg.png "encrdecr")
+
+---
+
+```
+n = pq
+e
+phi = (p-1)(q-1)
+d = e^-1 mod (phi) = e^-1 mod (p-1)(q-1)
+
+# encrypt
+c = m^e mod n = m^e mod pq
+
+# decrypt
+m' = c^d mod n = c ^(e^-1 mod (p-1)(q-1)) mod pq =
+ = (m^e)^(e^-1 mod (p-1)(q-1)) mod pq =
+ = m^(e * e^-1 mod (p-1)(q-1)) mod pq =
+ = m^(1 mod (p-1)(q-1)) mod pq =
+ [theorem in which we're not going into details]
+ a ^ (1 mod λ(N)) mod N = a mod N
+ [/theorem]
+ = m mod pq
+```
+
+
+---
+# Signature
+- encryption operation but using PrivK instead of PubK, and PubK instead of PrivK
+
+- having a message `m`
+- power of `m` at `d` of the private key from the signer person
+- evaluated at modulus `n`
+
+---
+
+### Example
+- private key of the person emitter of the signature: `d = 3, n = 33`
+- message to be signed: `m=5`
+- signature: `s = 5 ** 3 % 33 = 26`
+
+### Naive code
+```python
+def sign(privK, m):
+ s = (m ** privK.d) % privK.n
+ return s
+```
+
+---
+
+# Verification of the signature
+- having message `m` and the signature `s`
+- elevate `m` at `e` of the public key from the signer
+- evaluate at modulus of `n`
+
+---
+
+### Example
+- public key from the singer person `e=7, n=33`
+- message `m=5`
+- signature `s=26`
+- verification `v = 26**7 % 33 = 5`
+- check that we have recovered the message (that `m` is equivalent to `v`) `m = 5 = v = 5`
+
+### Naive code
+```python
+def verifySign(pubK, s, m):
+ v = (s ** pubK.e) % privK.n
+ return v==m
+```
+
+---
+
+# Homomorphic Multiplication
+- from two values $a$ and $b$
+- encrypted are $a_{encr}$ and $b_{encr}$
+- we can compute the multiplication of the two encrypted values, obtaining the result encrypted
+- the encrypted result from the multiplication is calculated doing: $c_{encr} = a_{encr} * b_{encr} mod n$
+- we can decrypt $c_{encr}$ and we will obtain $c$, equivalent to $a * b$
+
+- Why:
+```
+((a^e mod n) * (b^e mod n)) mod n =
+= (a^e * b^e mod n) mod n = (a*b)^e mod n
+```
+
+---
+
+### Example
+- PubK: `e=7, n=33`
+- PrivK: `d=3, n=33`
+- `a = 5`
+- `b = 8`
+- `a_encr = 5^7 mod 33 = 78125 mod 33 = 14`
+- `b_encr = 8^7 mod 33 = 2097152 mod 33 = 2`
+- `c_encr = (14 * 2) mod 33 = 28 mod 33 = 28`
+- `c = 28 ^ 3 mod 33 = 21952 mod 33 = 7`
+- `c = 7 = a * b % n = 5 * 8 % 33 = 7`, on `5*8 mod 33 = 7`
+- take a `n` enough big, if not the result will be cropped by the modulus
+
+---
+
+### Naive code
+```python
+def homomorphic_mul(pubK, a, b):
+ c = (a*b) % pubK.n
+ return c
+```
+
+---
+# Small demo
+[...]
+
+# And now... practical implementation
+- full night long
+- big ints are your friends
diff --git a/src/shamirsecretsharing/shamirsecretsharing.md b/src/shamirsecretsharing/shamirsecretsharing.md
new file mode 100644
index 0000000..0e96d3e
--- /dev/null
+++ b/src/shamirsecretsharing/shamirsecretsharing.md
@@ -0,0 +1,176 @@
+# Shamir's Secret Sharing
+
+
+
+- https://arnaucube.com
+- https://github.com/arnaucube
+- https://twitter.com/arnaucube
+
+
+
+
+ 2019-07-05
+
+
+---
+
+# Intro
+- I'm not an expert on the field, neither a mathematician. Just an engineer with interest for cryptography
+- Short talk (15 min), with the objective to make a practical introduction to the Shamir's Secret Sharing algorithm
+- Is not a talk about mathematical demostrations, is a talk with the objective to get the basic notions to be able to do a practical implementation of the algorithm
+- After the talk, we will do a practical workshop to implement the concepts. We can offer support for Go, Rust, Python and Nodejs (you can choose any other language, but we will not be able to help)
+
+---
+
+- Cryptographic algorithm
+- Created by Adi Shamir, in 1979
+ - also known by the $RSA$ cryptosystem
+ - explained in few months ago in a similar talk: https://github.com/arnaucube/slides/rsa
+
+---
+## What's this about?
+- imagine having a password that you want to share with 5 persons, in a way that they need to join their parts to get the original password
+- take the password, split it in 5 parts, and give one part to each one
+- when they need to recover it, they just need to get together, put all the pieces and recover the password (the `secret`)
+- this, has the problem that if a person looses its part, the secret will not be recovered anymore.. luckly we have a solution here:
+
+---
+
+- Shamir's Secret Sharing:
+ - from a secret to be shared, we generate 5 parts, but we can specify a number of parts that are needed to recover the secret
+ - so for example, we generate 5 parts, where we will need only 3 of that 5 parts to recover the secret, and the order doesn't matter
+ - we have the ability to define the thresholds of $M$ parts to be created, and $N$ parts to be able the recover
+
+---
+
+- 2 points are sufficient to define a line
+- 3 points are sufficient to define a parabola
+- 4 points are sufficient to define a cubic curve
+- $K$ points are suficient to define a polynomial of degree $k-1$
+
+We can create infinity of polynomials of degree 2, that goes through 2 points, but with 3 points, we can define a polynomial of degree 2 unique.
+
+![](https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/3_polynomials_of_degree_2_through_2_points.svg/220px-3_polynomials_of_degree_2_through_2_points.svg.png)
+
+---
+
+## Naming
+
+- `s`: secret
+- `m`: number of parts to be created
+- `n`: number of minimum parts necessary to recover the secret
+- `p`: random prime number, the Finite Field will be over that value
+
+---
+
+## Secret generation
+- we want that are necessary $n$ parts of $m$ to recover $s$
+ - where $n
+
+![](https://wikimedia.org/api/rest_v1/media/math/render/svg/6e2c3a2ab16a8723c0446de6a30da839198fb04b)
+
+---
+
+## Wikipedia example
+*example over real numbers, in the practical world, we use the algorithm in the Finite Field over $p$
+(more details: https://en.wikipedia.org/wiki/Shamir's_Secret_Sharing#Problem)
+- $s=1234$
+- $m=6$
+- $n=3$
+- $f(x) = \alpha_0 + \alpha_1 x + \alpha_2 x^2$
+ - $\alpha_0 = s = 1234$
+ - $\alpha_1 = 166$ *(random)*
+ - $\alpha_2 = 94$ *(random)*
+- $f(x) = 1234 + 166 x + 94 x^2$
+
+---
+
+- $f(x) = 1234 + 166 x + 94 x^2$
+- we calculate the points $P = (x, f(x))$
+ - where $x$ is each one of the values between $1$ and $m$
+ - $P_1=(1, f(1)) = (1, 1494)$
+ - $P_2=(2, f(2)) = (2, 1942)$
+ - $P_3=(3, f(3)) = (3, 2578)$
+ - $P_4=(4, f(4)) = (4, 3402)$
+ - $P_5=(5, f(5)) = (5, 4414)$
+ - $P_6=(6, f(6)) = (6, 5614)$
+---
+
+- to recover the secret, let's imagine that we take the packets 2, 4, 5
+ - $(x_0, y_0) = (2, 1942)$
+ - $(x_0, y_0) = (4, 3402)$
+ - $(x_0, y_0) = (5, 4414)$
+
+---
+
+- let's calculate the Lagrange Interpolation
+ - ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/388471f79b8d3bdb75851b99ed15e5849329cc84)
+ - ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/3c853bdf0daa2db92cd70a6ab21dfd858296cfdd)
+ - ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/2013ee56aba68b07d8d4a2c6578e77ff8e8940ff)
+ - ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/32fc145272d82d9ebf62b4e30a05eac2b7d2873a)
+- obtaining $f(x) = \alpha_0 + \alpha_1 x + \alpha_2 x^2$, where $\alpha_0$ is the secret $s$ recovered
+ - where we eavluate the polynomial at $f(0)$, obtaining $\alpha_0 = s$
+- *we are not going into details now, but if you want in the practical workshop we can analyze the 'mathematical' part of all of this
+
+---
+
+# And now... practical implementation
+- full night long
+- big ints are your friends
+- $L(x) = \sum_{j=0}^{n} y_j l_j(x)$
+![](https://wikimedia.org/api/rest_v1/media/math/render/svg/6e2c3a2ab16a8723c0446de6a30da839198fb04b)
+
+# About
+
+
+
+- https://arnaucube.com
+- https://github.com/arnaucube
+- https://twitter.com/arnaucube
+
+
+
+
+ 2019-07-05
+
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/demo/go.mod b/src/zksnarks-from-scratch-a-technical-explanation/demo/go.mod
new file mode 100644
index 0000000..f809562
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/demo/go.mod
@@ -0,0 +1,8 @@
+module demo
+
+go 1.12
+
+require (
+ github.com/arnaucube/go-snark v0.0.4 // indirect
+ github.com/stretchr/testify v1.4.0 // indirect
+)
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/demo/go.sum b/src/zksnarks-from-scratch-a-technical-explanation/demo/go.sum
new file mode 100644
index 0000000..4b78653
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/demo/go.sum
@@ -0,0 +1,15 @@
+github.com/arnaucube/go-snark v0.0.4 h1:JJbQx/wg0u1mzJk9Of/rqCkclPgXuvPrLWHfvgnoyEE=
+github.com/arnaucube/go-snark v0.0.4/go.mod h1:m1VkAgz3F+Jdighf2n5eMLe670AR6fBhBGfVHwz2QRk=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/demo/main.go b/src/zksnarks-from-scratch-a-technical-explanation/demo/main.go
new file mode 100644
index 0000000..76ad159
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/demo/main.go
@@ -0,0 +1,109 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "math/big"
+ "strings"
+ "time"
+
+ "github.com/arnaucube/go-snark"
+ "github.com/arnaucube/go-snark/circuitcompiler"
+)
+
+func main() {
+ // circuit function
+ // y = x^5 + 2*x + 6
+ code := `
+ func exp5(private a):
+ b = a * a
+ c = a * b
+ d = a * c
+ e = a * d
+ return e
+
+ func main(private s0, public s1):
+ s2 = exp5(s0)
+ s3 = s0 * 2
+ s4 = s3 + s2
+ s5 = s4 + 6
+ equals(s1, s5)
+ out = 1 * 1
+ `
+ fmt.Print("\ncode of the circuit:")
+ fmt.Println(code)
+
+ // parse the code
+ parser := circuitcompiler.NewParser(strings.NewReader(code))
+ circuit, err := parser.Parse()
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println("\ncircuit data:", circuit)
+ circuitJson, _ := json.Marshal(circuit)
+ fmt.Println("circuit:", string(circuitJson))
+
+ b8 := big.NewInt(int64(8))
+ privateInputs := []*big.Int{b8}
+ b32790 := big.NewInt(int64(32790))
+ publicSignals := []*big.Int{b32790}
+
+ // wittness
+ w, err := circuit.CalculateWitness(privateInputs, publicSignals)
+ if err != nil {
+ panic(err)
+ }
+
+ // code to R1CS
+ fmt.Println("\ngenerating R1CS from code")
+ a, b, c := circuit.GenerateR1CS()
+ fmt.Println("\nR1CS:")
+ fmt.Println("a:", a)
+ fmt.Println("b:", b)
+ fmt.Println("c:", c)
+
+ // R1CS to QAP
+ // TODO zxQAP is not used and is an old impl, TODO remove
+ alphas, betas, gammas, _ := snark.Utils.PF.R1CSToQAP(a, b, c)
+ fmt.Println("qap")
+ fmt.Println(alphas)
+ fmt.Println(betas)
+ fmt.Println(gammas)
+
+ _, _, _, px := snark.Utils.PF.CombinePolynomials(w, alphas, betas, gammas)
+
+ // calculate trusted setup
+ setup, err := snark.GenerateTrustedSetup(len(w), *circuit, alphas, betas, gammas)
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println("\nt:", setup.Toxic.T)
+
+ // zx and setup.Pk.Z should be the same (currently not, the correct one is the calculation used inside GenerateTrustedSetup function), the calculation is repeated. TODO avoid repeating calculation
+
+ proof, err := snark.GenerateProofs(*circuit, setup.Pk, w, px)
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println("\n proofs:")
+ fmt.Println(proof)
+
+ // fmt.Println("public signals:", proof.PublicSignals)
+ fmt.Println("\nsignals:", circuit.Signals)
+ fmt.Println("witness:", w)
+ b32790Verif := big.NewInt(int64(32790))
+ publicSignalsVerif := []*big.Int{b32790Verif}
+ before := time.Now()
+ if !snark.VerifyProof(setup.Vk, proof, publicSignalsVerif, true) {
+ fmt.Println("Verification not passed")
+ }
+ fmt.Println("verify proof time elapsed:", time.Since(before))
+
+ // check that with another public input the verification returns false
+ bOtherWrongPublic := big.NewInt(int64(34))
+ wrongPublicSignalsVerif := []*big.Int{bOtherWrongPublic}
+ if snark.VerifyProof(setup.Vk, proof, wrongPublicSignalsVerif, true) {
+ fmt.Println("Verification should not have passed")
+ }
+}
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/arnaucube.png b/src/zksnarks-from-scratch-a-technical-explanation/imgs/arnaucube.png
new file mode 100644
index 0000000..ebdcb22
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/arnaucube.png differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat00.jpeg b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat00.jpeg
new file mode 100644
index 0000000..1bc5348
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat00.jpeg differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat01.jpeg b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat01.jpeg
new file mode 100644
index 0000000..c3df3b3
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat01.jpeg differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat02.jpeg b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat02.jpeg
new file mode 100644
index 0000000..c92db08
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat02.jpeg differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat03.jpeg b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat03.jpeg
new file mode 100644
index 0000000..5d72207
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat03.jpeg differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat04.jpeg b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat04.jpeg
new file mode 100644
index 0000000..86ecfb4
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat04.jpeg differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat05.jpeg b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat05.jpeg
new file mode 100644
index 0000000..ea85eed
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/cat05.jpeg differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/iden3.png b/src/zksnarks-from-scratch-a-technical-explanation/imgs/iden3.png
new file mode 100644
index 0000000..7d42e8b
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/iden3.png differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/qap-screenshot.png b/src/zksnarks-from-scratch-a-technical-explanation/imgs/qap-screenshot.png
new file mode 100644
index 0000000..af519f2
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/qap-screenshot.png differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-concept-flow.png b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-concept-flow.png
new file mode 100644
index 0000000..1a43fd9
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-concept-flow.png differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-concept-flow.xml b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-concept-flow.xml
new file mode 100644
index 0000000..741593e
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-concept-flow.xml
@@ -0,0 +1 @@
+5Vldb5swFP01edyEMRDy2NCvSZu0Ldu6Pk0OXMCtwcgxTbJfPwMmQKFdqpGiqalUcY99zeX4HMglM+wluytBsvgTD4DNTCPYzfD5zDTxHKn/BbCvgLnhVkAkaFBBqAFW9Ddo0NBoTgPYdCZKzpmkWRf0eZqCLzsYEYJvu9NCzrpnzUgEPWDlE9ZHb2ggY40iw2gGroFGsT61a+uBhNSTNbCJScC3LQhfzLAnOJfVUbLzgBXc1bxUeZdPjB4KE5DKYxJ+ba6tm/P766UHd/g7OeN3Hx7emdUqD4Tl+oJ1sXJfMyB4ngZQLGLM8HIbUwmrjPjF6FZtucJimTAVIXWolwMhYfdknehw9Uo1wBOQYq+m6ISF5ksLBjk63rbor+fELeaRpUGitzw6LN2wog40MS8gyelxAoESiQ65kDGPeErYRYMuu6w1cz5ynmmu7kDKvVY8ySUfYrI40fM8qrp4Lnx4pn6sfUNEBPKZedbwvghgRNKHbh2jk4x7SrxUp5WQKhJLe2+kIDSVm38TaEgZ8zjjoszFoeuD7ytcrc7voTWydm3LNsaRNEKPNL0Y0LQ9oGl8KkkvppA07Kj8WaS/t3V02xo53+mVy2BfB6m63FZSEd62x5q0MqrzRrSPdaR93CntY/Xs8xV5q3G9EoIz7JVgvlgbY3nFsjteMW275xX3Na2C8CRemV737pG6R+aUwnd7wv9y9nlk3YfmE7p31o7tnEb32Jxa96jH4tvQff2w/qvw8ZS6r6tsCd9Tzde4yreLvyHlO+WnyOCpbOHV5zSOOHyLmswR9lt1hHnso2DSFqIus2WJbyLfyLKDWIHMs1HdEdjgBtaQO1xzjZ2xngu42ztgt/9cODjjdWwwn8QG/2fzgI7tHpAzqXX6/cNnwXmooCvVggtVAk/HdQ8BNxz8VuX4LqzD07jHsiZ3j9Nj+gcIGlJ/fI4BqXvUfIjjhTPH5ER3KNuYnON+U+BR4edUlq+SkowyED2mFQOyS2eXtpSn8IhjDRFGo1SFvmJMLYyXBZ9qQ9mZHkhoEJS3waH96+7wGBtyxCvUoTeo5sv3Q4XNG+xyrPUzAL74Aw==
\ No newline at end of file
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-prover.png b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-prover.png
new file mode 100644
index 0000000..3f448b7
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-prover.png differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-prover.xml b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-prover.xml
new file mode 100644
index 0000000..06759c3
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-prover.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-verifier.png b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-verifier.png
new file mode 100644
index 0000000..e2dd2ca
Binary files /dev/null and b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-verifier.png differ
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-verifier.xml b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-verifier.xml
new file mode 100644
index 0000000..014e84b
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/imgs/zksnark-verifier.xml
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/zksnarks-from-scratch-a-technical-explanation/zksnarks-from-scratch-a-technical-explanation.md b/src/zksnarks-from-scratch-a-technical-explanation/zksnarks-from-scratch-a-technical-explanation.md
new file mode 100644
index 0000000..f830610
--- /dev/null
+++ b/src/zksnarks-from-scratch-a-technical-explanation/zksnarks-from-scratch-a-technical-explanation.md
@@ -0,0 +1,877 @@
+# zkSNARKs from scratch, a technical explanation
+
+
+
+
+
+[arnaucube.com](https://arnaucube.com)
+[github.com/arnaucube](https://github.com/arnaucube)
+[twitter.com/arnaucube](https://twitter.com/arnaucube)
+
+
+ 2019-08-20
+
+
+
+[iden3.io](https://iden3.io)
+[github.com/iden3](https://github.com/iden3)
+[twitter.com/identhree](https://twitter.com/identhree)
+
+
+---
+
+## Warning
+
+
+
+- I'm not a mathematician, this talk is not for mathematicians
+
+- In free time, have been studying zkSNARKS & implementing it in Go
+
+- Talk about a technical explaination from an engineer point of view
+- The idea is to try to transmit the learnings from long night study hours during last winter
+- Also at the end will briefly overview how we use zkSNARKs in iden3
+- This slides will be combined with
+ - parts of the code from https://github.com/arnaucube/go-snark
+ - whiteboard draws and writtings
+- Don't use your own crypto. But it's fun to implement it (only for learning purposes)
+
+
+
+---
+
+## Contents
+
+
+
+- Introduction
+ - zkSNARK overview
+ - zkSNARK flow
+ - Generating and verifying proofs
+- Foundations
+ - Basics of modular arithmetic
+ - Groups
+ - Finite fields
+ - Elliptic curve operations
+- Pairings
+ - Bilinear Pairings
+ - BLS signatures
+
+
+
+---
+
+
+
+- zkSNARK (Pinocchio)
+ - Circuit compiler
+ - R1CS
+ - QAP
+ - Lagrange Interpolation
+ - Trusted Setup
+ - Proofs generation
+ - Proofs verification
+- Groth16
+- How we use zkSNARKs in iden3
+- libraries
+- Circuit languages
+- utilities (Elliptic curve & Hash functions) inside the zkSNARK libraries
+ - BabyJubJub
+ - Mimc
+ - Poseidon
+- References
+
+
+
+---
+
+## Introduction
+- zero knowledge concept
+- examples
+- some concept explanations
+ - https://en.wikipedia.org/wiki/Zero-knowledge_proof
+ - https://hackernoon.com/wtf-is-zero-knowledge-proof-be5b49735f27
+
+---
+
+
+## zkSNARK overview
+
+
+- protocol to prove the correctness of a computation
+- useful for
+ - scalability
+ - privacy
+ - interoperability
+- examples:
+ - Alice can prove to Brenna that knows $x$ such as $f(x) = y$
+ - Brenna can prove to Alice that knows a certain input which $Hash$ results in a certain known value
+ - Carol can proof that is a member of an organization without revealing their identity
+ - etc
+
+---
+
+### zkSNARK flow
+
+
+
+
+
+---
+
+
+### Generating and verifying proofs
+Generating a proof:
+
+
+
+
+
+
+
+Verifying a proof:
+
+
+
+
+
+
+---
+
+
+## Foundations
+- Modular aritmetic
+- Groups
+- Finite fields
+- Elliptic Curve Cryptography
+
+---
+
+## Basics of modular arithmetic
+- Modulus, `mod`, `%`
+- Remainder after division of two numbers
+
+![clocks](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Clock_group.svg/220px-Clock_group.svg.png "clocks")
+
+```python
+5 mod 12 = 5
+14 mod 12 = 2
+83 mod 10 = 3
+```
+
+```python
+5 + 3 mod 6 = 8 mod 6 = 2
+```
+
+
+---
+
+## Groups
+- a **set** with an **operation**
+ - **operation** must be *associative*
+- neutral element ($identity$): adding the neutral element to any element gives the element
+- inverse: $e$ + $e_{inverse}$ = $identity$
+- cyclic groups
+ - finite group with a generator element
+ - any element must be writable by a multiple of the generator element
+- abelian group
+ - group with *commutative* operation
+
+---
+
+## Finite fields
+- algebraic structure like Groups, but with **two operations**
+- extended fields concept (https://en.wikipedia.org/wiki/Field_extension)
+
+---
+
+## Elliptic curve
+- point addition
+
+$(x_1, y_1) + (x_2, y_2) =
+(\dfrac{
+x_1 y_2 + x_2 y_1
+}{
+1 + d x_1 x_2 y_1 y_2
+},
+\dfrac{
+y_1 y_2 - x_1 x_2
+}{
+1-dx_1 x_2 y_1 y_2
+})$
+- G1
+- G2
+
+*(whiteboard explanation)*
+
+---
+
+## Pairings
+- 3 typical types used for SNARKS:
+ - BN (Barreto Naehrig) - used in Ethereum
+ - BLS (Barreto Lynn Scott) - used in ZCash & Ethereum 2.0
+ - MNT (Miyaji- Nakabayashi - Takano) - used in CodaProtocol
+- $y^2 = x^3 + b$ with embedding degree 12
+- function that maps (pairs) two points from sets `S1` and `S2` into another set `S3`
+- is a [bilinear](https://en.wikipedia.org/wiki/Bilinear_map) function
+- $e(G_1, G_2) -> G_T$
+- the groups must be
+ - cyclic
+ - same prime order ($r$)
+
+---
+
+- $F_q$, where $q=$`21888242871839275222246405745257275088696311157297823662689037894645226208583`
+- $F_r$, where $r=$`21888242871839275222246405745257275088548364400416034343698204186575808495617`
+
+---
+
+## Bilinear Pairings
+$e(P_1 + P_2, Q_1) == e(P_1, Q_1) \cdot e(P_2, Q_1)$
+
+$e(P_1, Q_1 + Q_2) == e(P_1, Q_1) \cdot e(P_1, Q_2)$
+
+$e(aP, bQ) == e(P, Q)^{ab} == e(bP, aQ)$
+
+
+
+$e(g_1, g_2)^6 == e(g_1, 6 \cdot g_2)$
+
+$e(g_1, g_2)^6 == e(6 \cdot g_1, g_2)$
+
+$e(g_1, g_2)^6 == e(3 \cdot g_1, 2 g_2)$
+
+$e(g_1, g_2)^6 == e(2 \cdot g_1, 3 g_2)$
+
+
+---
+
+### BLS signatures
+*(small overview, is offtopic here, but is interesting)*
+- key generation
+ - random private key $x$ in $[0, r-1]$
+ - public key $g^x$
+- signature
+ - $h=Hash(m)$ (over G2)
+ - signature $\sigma=h^x$
+- verification
+ - check that: $e(g, \sigma) == e(g^x, Hash(m))$
+ $e(g, h^x) == e(g^x, h)$
+
+
+---
+
+- aggregate signatures
+ - $s = s0 + s1 + s2 ...$
+- verify aggregated signatures
+
+
+
+$e(G,S) == e(P, H(m))$
+
+$e(G, s0+s1+s2...) == e(p0, H(m)) \cdot e(p1, H(m)) \cdot e(p2, H(m)) ...$
+
+
+
+
+More info: https://crypto.stanford.edu/~dabo/pubs/papers/BLSmultisig.html
+
+---
+
+## Circuit compiler
+- not a software compiler -> a constraint prover
+ - what this means
+- constraint concept
+ - `value0` == `value1` `` `value2`
+- want to proof that a certain computation has been done correctly
+- graphic of circuit with gates (whiteboard)
+
+- about high level programing languages for zkSNARKS, by *Harry Roberts*: https://www.youtube.com/watch?v=nKrBJo3E3FY
+
+---
+
+Circuit code example:
+$f(x) = x^5 + 2\cdot x + 6$
+
+```
+func exp5(private a):
+ b = a * a
+ c = a * b
+ d = a * c
+ e = a * d
+ return e
+
+func main(private s0, public s1):
+ s2 = exp5(s0)
+ s3 = s0 * 2
+ s4 = s3 + s2
+ s5 = s4 + 6
+ equals(s1, s5)
+ out = 1 * 1
+```
+
+---
+
+## Inputs and Witness
+For a certain circuit, with the inputs that we calculate the Witness for the circuit signals
+- private inputs: `[8]`
+ - in this case the private input is the 'secret' $x$ value that computed into the equation gives the expected $f(x)$
+- public inputs: `[32790]`
+ - in this case the public input is the result of the equation
+- signals: `[one s1 s0 b0 c0 d0 s2 s3 s4 s5 out]`
+- witness: `[1 32790 8 64 512 4096 32768 16 32784 32790 1]`
+
+---
+
+## R1CS
+- Rank 1 Constraint System
+- way to write down the constraints by 3 linear combinations
+- 1 constraint per operation
+- $(A, B, C) = A.s \cdot B.s - C.s = 0$
+- from flat code constraints we can generate the R1CS
+
+---
+
+## R1CS
+
+
+
+$(a_{11}s_1 + a_{12}s_2 + ... + a_{1n}s_n) \cdot (b_{11}s_1 + b_{12}s_2 + ... + b_{1n}s_n) - (c_{11}s_1 + c_{12}s_2 + ... + c_{1n}s_n) = 0$
+
+$(a_{21}s_1 + a_{22}s_2 + ... + a_{2n}s_n) \cdot (b_{21}s_1 + b_{22}s_2 + ... + b_{2n}s_n) - (c_{21}s_1 + c_{22}s_2 + ... + c_{2n}s_n) = 0$
+$(a_{31}s_1 + a_{32}s_2 + ... + a_{3n}s_n) \cdot (b_{31}s_1 + b_{32}s_2 + ... + b_{3n}s_n) - (c_{31}s_1 + c_{32}s_2 + ... + c_{3n}s_n) = 0$
+[...]
+$(a_{m1}s_1 + a_{m2}s_2 + ... + a_{mn}s_n) \cdot (b_{m1}s_1 + b_{m2}s_2 + ... + b_{mn}s_n) - (c_{m1}s_1 + c_{m2}s_2 + ... + c_{mn}s_n) = 0$
+
+*where $s$ are the signals of the circuit, and we need to find $a, b, c$ that satisfies the equations
+
+
+---
+
+R1CS constraint example:
+- signals: `[one s1 s0 b0 c0 d0 s2 s3 s4 s5 out]`
+- witness: `[1 32790 8 64 512 4096 32768 16 32784 32790 1]`
+- First constraint flat code: `b0 == s0 * s0`
+- R1CS first constraint:
+$A_1 = [00100000000]$
+$B_1 = [00100000000]$
+$C_1 = [00010000000]$
+
+---
+
+R1CS example:
+
+| $A$| $B$ | $C$: |
+|-|-|-|
+| $[0 0 1 0 0 0 0 0 0 0 0]$
$[0 0 1 0 0 0 0 0 0 0 0]$
$[0 0 1 0 0 0 0 0 0 0 0]$
$[0 0 1 0 0 0 0 0 0 0 0]$
$[0 0 1 0 0 0 0 0 0 0 0]$
$[0 0 0 0 0 0 1 1 0 0 0]$
$[6 0 0 0 0 0 0 0 1 0 0]$
$[0 0 0 0 0 0 0 0 0 1 0]$
$[0 1 0 0 0 0 0 0 0 0 0]$
$[1 0 0 0 0 0 0 0 0 0 0]$ | $[0 0 1 0 0 0 0 0 0 0 0]$
$[0 0 0 1 0 0 0 0 0 0 0]$
$[0 0 0 0 1 0 0 0 0 0 0]$
$[0 0 0 0 0 1 0 0 0 0 0]$
$[2 0 0 0 0 0 0 0 0 0 0]$
$[1 0 0 0 0 0 0 0 0 0 0]$
$[1 0 0 0 0 0 0 0 0 0 0]$
$[1 0 0 0 0 0 0 0 0 0 0]$
$[1 0 0 0 0 0 0 0 0 0 0]$
$[1 0 0 0 0 0 0 0 0 0 0]$ | $[0 0 0 1 0 0 0 0 0 0 0]$
$[0 0 0 0 1 0 0 0 0 0 0]$
$[0 0 0 0 0 1 0 0 0 0 0]$
$[0 0 0 0 0 0 1 0 0 0 0]$
$[0 0 0 0 0 0 0 1 0 0 0]$
$[0 0 0 0 0 0 0 0 1 0 0]$
$[0 0 0 0 0 0 0 0 0 1 0]$
$[0 1 0 0 0 0 0 0 0 0 0]$
$[0 0 0 0 0 0 0 0 0 1 0]$
$[0 0 0 0 0 0 0 0 0 0 1]$ |
+
+
+---
+
+## QAP
+- Quadratic Arithmetic Programs
+- 3 polynomials, linear combinations of R1CS
+- very good article about QAP by Vitalik Buterin https://medium.com/@VitalikButerin/quadratic-arithmetic-programs-from-zero-to-hero-f6d558cea649
+
+---
+
+![qap](imgs/qap-screenshot.png)
+
+---
+
+### Lagrange Interpolation
+(Polynomial Interpolation)
+- for a group of points, we can find the smallest degree polynomial that goees through all that points
+ - this polynomial is unique for each group of points
+
+![](https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Lagrange_polynomial.svg/440px-Lagrange_polynomial.svg.png)
+
+---
+
+$L(x) = \sum_{j=0}^{n} y_j l_j(x)$
+
+
+
+![](https://wikimedia.org/api/rest_v1/media/math/render/svg/6e2c3a2ab16a8723c0446de6a30da839198fb04b)
+
+
+---
+
+#### Shamir's Secret Sharing
+*(small overview, is offtopic here, but is interesting)*
+
+- from a secret to be shared, we generate 5 parts, but we can specify a number of parts that are needed to recover the secret
+- so for example, we generate 5 parts, where we will need only 3 of that 5 parts to recover the secret, and the order doesn't matter
+- we have the ability to define the thresholds of $M$ parts to be created, and $N$ parts to be able the recover
+
+---
+
+##### Shamir's Secret Sharing - Secret generation
+- we want that are necessary $n$ parts of $m$ to recover $s$
+ - where $n
+
+$(\alpha_1(x)s_1 + \alpha_2(x)s_2 + ... + \alpha_n(x)s_n) \cdot (\beta_1(x)s_1 + \beta_2(x)s_2 + ... + \beta_n(x)s_n) - (\gamma_1(x)s_1 + \gamma_2(x)s_2 + ... + \gamma_n(x)s_n) = P(x)$
+
+|----------------------- $A(x)$ -----------------------|------------------------ $B(x)$ -----------------------|------------------------ $C(x)$ ------------------------|
+
+
+
+
+
+- $P(x) = A(x)B(x)-C(x)$
+- $P(x) = Z(x) h(x)$
+- $Z(x)$: divisor polynomial
+ - $Z(x) = (x - x_1)(x-x_2)...(x-x_m) => ...=> (x_1, 0), (x_2, 0), ..., (x_m, 0)$
+ - optimizations with FFT
+- $h(x) = P(x) / Z(x)$
+
+
+
+---
+
+*The following explanation is for the [Pinocchio protocol](https://eprint.iacr.org/2013/279.pdf), all the examples will be for this protocol. The [Groth16](https://eprint.iacr.org/2016/260.pdf) is explained also in the end of this slides.*
+
+---
+
+## Trusted Setup
+- concept
+- $\tau$ (Tau)
+- "Toxic waste"
+- Proving Key
+- Verification Key
+
+---
+
+$g_1 t^0, g_1 t^1, g_1 t^2, g_1 t^3, g_1 t^4, ...$
+$g_2 t^0, g_2 t^1, g_2 t^2, g_2 t^3, g_2 t^4, ...$
+
+---
+
+Proving Key:
+$pk = (C, pk_A, pk_A', pk_B, pk_B', pk_C, pk_C', pk_H)$ where:
+- $pk_A = \{ A_i(\tau) \rho_A P_1 \}^{m+3}_{i=0}$
+- $pk_A' = \{ A_i(\tau) \alpha_A \rho_A P_1 \}^{m+3}_{i=n+1}$
+- $pk_B = \{ B_i(\tau) \rho_B P_2 \}^{m+3}_{i=0}$
+- $pk_B' = \{ B_i(\tau) \alpha_B \rho_B P_1 \}^{m+3}_{i=0}$
+- $pk_C = \{ C_i(\tau) \rho_C P_1 \}^{m+3}_{i=0} = \{C_i(\tau) \rho_A \rho_B P_1\}^{m+3}_{i=0}$
+- $pk_C' = \{ C_i(\tau) \alpha_C \rho_C P_1 \}^{m+3}_{i=0} = \{ C_i(\tau) \alpha_C \rho_A \rho_B P_1 \}^{m+3}_{i=0}$
+- $pk_K = \{ \beta (A_i(\tau) \rho_A + B_i(\tau) \rho_B C_i(\tau) \rho_A \rho_B) P_1 \} ^{m+3}_{i=0}$
+- $pk_H = \{ \tau^i P_1 \}^d_{i=0}$
+
+where:
+- $d$: degree of polynomial $Z(x)$
+- $m$: number of circuit signals
+
+---
+
+Verification Key:
+$vk = (vk_A, vk_B, vk_C, vk_\gamma, vk^1_{\beta\gamma}, vk^2_{\beta\gamma}, vk_Z, vk_{IC})$
+- $vk_A = \alpha_A P_2$, $vk_B = \alpha_B P_1$, $vk_C = \alpha_C P_2$
+- $vk_{\beta\gamma} = \gamma P_2$, $vk^1_{\beta\gamma} = \beta\gamma P_1$, $vk^2_{\beta\gamma} = \beta\gamma P_2$
+- $vk_Z = Z(\tau) \rho_A \rho_B P_2$, $vk_{IC} = (A_i(\tau) \rho_A P_1)^n_{i=0}$
+
+---
+
+```go
+type Pk struct { // Proving Key pk:=(pkA, pkB, pkC, pkH)
+ G1T [][3]*big.Int // t encrypted in G1 curve, G1T == Pk.H
+ A [][3]*big.Int
+ B [][3][2]*big.Int
+ C [][3]*big.Int
+ Kp [][3]*big.Int
+ Ap [][3]*big.Int
+ Bp [][3]*big.Int
+ Cp [][3]*big.Int
+ Z []*big.Int
+}
+
+type Vk struct {
+ Vka [3][2]*big.Int
+ Vkb [3]*big.Int
+ Vkc [3][2]*big.Int
+ IC [][3]*big.Int
+ G1Kbg [3]*big.Int // g1 * Kbeta * Kgamma
+ G2Kbg [3][2]*big.Int // g2 * Kbeta * Kgamma
+ G2Kg [3][2]*big.Int // g2 * Kgamma
+ Vkz [3][2]*big.Int
+}
+```
+
+---
+
+```go
+// Setup is the data structure holding the Trusted Setup data. The Setup.Toxic sub struct must be destroyed after the GenerateTrustedSetup function is completed
+type Setup struct {
+ Toxic struct {
+ T *big.Int // trusted setup secret
+ Ka *big.Int
+ Kb *big.Int
+ Kc *big.Int
+ Kbeta *big.Int
+ Kgamma *big.Int
+ RhoA *big.Int
+ RhoB *big.Int
+ RhoC *big.Int
+ }
+ Pk Pk
+ Vk Vk
+}
+```
+
+---
+
+## Proofs generation
+- $A, B, C, Z$ (from the QAP)
+- random $\delta_1, \delta_2, \delta_3$
+- $H(z)= \dfrac{A(z)B(z)-C(z)}{Z(z)}$
+ - $A(z) = A_0(z) + \sum_{i=1}^m s_i A_i(x) + \delta_1 Z(z)$
+ - $B(z) = B_0(z) + \sum_{i=1}^m s_i B_i(x) + \delta_2 Z(z)$
+ - $C(z) = C_0(z) + \sum_{i=1}^m s_i B_i(x) + \delta_2 Z(z)$
+(where $m$ is the number of public inputs)
+
+---
+
+- $\pi_A = $
+- $\pi_A' = $
+- $\pi_B = $
+ - example:
+ ```go
+ for i := 0; i < circuit.NVars; i++ {
+ proof.PiB = Utils.Bn.G2.Add(proof.PiB, Utils.Bn.G2.MulScalar(pk.B[i], w[i]))
+ proof.PiBp = Utils.Bn.G1.Add(proof.PiBp, Utils.Bn.G1.MulScalar(pk.Bp[i], w[i]))
+ }
+ ```
+($c=1+witness+\delta_1+\delta_2+\delta_3$
+- $\pi_B' = $
+- $\pi_C = $
+- $\pi_C' = $
+- $\pi_K = $
+- $\pi_H = $
+- proof: $\pi = (\pi_A, \pi_A', \pi_B, \pi_B', \pi_C, \pi_C', \pi_K, \pi_H$
+
+---
+
+## Proofs verification
+
+
+
+- $vk_{kx} = vk_{IC,0} + \sum_{i=1}^n x_i vk_{IC,i}$
+
+Verification:
+- $e(\pi_A, vk_a) == e(\pi_{A'}, g_2)$
+- $e(vk_b, \pi_B) == e(\pi_{B'}, g_2)$
+- $e(\pi_C, vk_c) == e(\pi_{C'}, g_2)$
+- $e(vk_{kx}+\pi_A, \pi_B) == e(\pi_H, vk_{kz}) \cdot e(\pi_C, g_2)$
+- $e(vk_{kx} + \pi_A + \pi_C, V_{\beta\gamma}^2) \cdot e(vk_{\beta\gamma}^1, \pi_B) == e(\pi_k, vk_{\gamma}^1)$
+
+---
+
+
+
+Example (whiteboard):
+
+
+$\dfrac{
+ e(\pi_A, \pi_B)
+}{
+ e(\pi_C, g_2)
+}
+= e(g_1 h(t), g_2 z(t))
+$
+
+$\dfrac{
+ e(A_1 + A_2 + ... + A_n, B_1 + B_2 + ... + B_n)
+}{
+ e(C_1 + C_2 + ... + C_n, g_2)
+}
+= e(g_1 h(t), g_2 z(t))
+$
+
+$\dfrac{
+ e(g_1 \alpha_1(t) s_1 + g_1 \alpha_2(t) s_2 + ... + g_1 \alpha_n(t) s_n, g_2 \beta_1(t)s_1 + g_2 \beta_2(t) s_2 + ... + g_2 \beta_n(t) s_n)
+}{
+ e(g_1 \gamma_1(t) s_1 + g_1 \gamma_2(t) s_2 + ... + g_1 \gamma_n(t) s_n, g_2)
+}
+= e(g_1 h(t), g_2 z(t))
+$
+
+$
+e(g_1 \alpha_1(t) s_1 + g_1 \alpha_2(t) s_2 + ... + g_1 \alpha_n(t) s_n, g_2 \beta_1(t)s_1 + g_2 \beta_2(t) s_2 + ... + g_2 \beta_n(t) s_n)$
+$= e(g_1 h(t), g_2 z(t)) \cdot e(g_1 \gamma_1(t) s_1 + g_1 \gamma_2(t) s_2 + ... + g_1 \gamma_n(t) s_n, g_2)
+$
+
+
+
+
+---
+
+## Groth16
+
+
+
+
+### Trusted Setup
+$\tau = \alpha, \beta, \gamma, \delta, x$
+
+$\sigma_1 =$
+- $\alpha, \beta, \delta, \{ x^i\}_{i=0}^{n-1}$
+
+- $\{
+\dfrac{
+\beta u_i(x) + \alpha v_i(x) + w_i(x)
+}{
+\gamma
+}
+\}_{i=0}^l$
+
+- $\{
+\dfrac{
+\beta u_i(x) + \alpha v_i(x) + w_i(x)
+}{
+\delta
+}
+\}_{i=l+1}^m$
+
+- $\{
+\dfrac{x^i t(x)}{\delta}
+\}_{i=0}^{n-2}$
+
+$\sigma_2 = (\beta, \gamma, \delta, \{ x^i \}_{i=0}^{n-1})$
+
+*(where $u_i(x), v_i(x), w_i(x)$ are the $QAP$)*
+
+---
+
+```go
+type Pk struct { // Proving Key
+ BACDelta [][3]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / δ } from l+1 to m
+ Z []*big.Int
+ G1 struct {
+ Alpha [3]*big.Int
+ Beta [3]*big.Int
+ Delta [3]*big.Int
+ At [][3]*big.Int // {a(τ)} from 0 to m
+ BACGamma [][3]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / γ } from 0 to m
+ }
+ G2 struct {
+ Beta [3][2]*big.Int
+ Gamma [3][2]*big.Int
+ Delta [3][2]*big.Int
+ BACGamma [][3][2]*big.Int // {( βui(x)+αvi(x)+wi(x) ) / γ } from 0 to m
+ }
+ PowersTauDelta [][3]*big.Int // powers of τ encrypted in G1 curve, divided by δ
+}
+```
+
+---
+
+```go
+type Vk struct {
+ IC [][3]*big.Int
+ G1 struct {
+ Alpha [3]*big.Int
+ }
+ G2 struct {
+ Beta [3][2]*big.Int
+ Gamma [3][2]*big.Int
+ Delta [3][2]*big.Int
+ }
+}
+```
+
+
+---
+
+```go
+// Setup is the data structure holding the Trusted Setup data. The Setup.Toxic sub struct must be destroyed after the GenerateTrustedSetup function is completed
+type Setup struct {
+ Toxic struct {
+ T *big.Int // trusted setup secret
+ Kalpha *big.Int
+ Kbeta *big.Int
+ Kgamma *big.Int
+ Kdelta *big.Int
+ }
+ Pk Pk
+ Vk Vk
+}
+```
+
+---
+
+#
+## Proofs Generation
+$\pi_A=\alpha + \sum_{i=0}^m \alpha_i u_i(x) + r \delta$
+$\pi_B=\beta + \sum_{i=0}^m \alpha_i v_i(x) + s \delta$
+
+
+
+$\pi_C = \dfrac{
+\sum_{i=l+1}^m a_i(\beta u_i(x) + \alpha v_i(x) + w_i(x)) + h(x)t(x)
+}{
+\delta
+} + \pi_As + \pi_Br -rs\delta$
+
+
+
+$\pi=\pi_A^1, \pi_B^1, \pi_C^2$
+
+---
+
+### Proof Verification
+
+
+
+$[\pi_A]_1 \cdot [\pi_B]_2 = [\alpha]_1 \cdot [\beta]_2 +
+\sum_{i=0}^l a_i [
+\dfrac{
+\beta u_i(x) + \alpha v_i(x) + w_i(x)
+}{
+\gamma
+}
+]_1
+\cdot [\gamma]_2 + [\pi_C]_1 \cdot [\delta]_2
+$
+
+
+
+$e(\pi_A, \pi_B) = e(\alpha, \beta) \cdot e(pub, \gamma) \cdot e(\pi_C, \delta)$
+
+
+---
+
+## How we use zkSNARKs in iden3
+- proving a credentials without revealing it's content
+- proving that an identity has a claim issued by another identity, without revealing all the data
+- proving any property of an identity
+- $ITF$ (Identity Transition Function), a way to prove with a zkSNARK that an identity has been updated following the defined protocol
+ - identities can not cheat when issuing claims
+- etc
+
+## Other ideas for free time side project
+- Zendermint (Tendermint + zkSNARKs)
+
+---
+
+
+
+
+## zkSNARK libraries
+- [bellman](https://github.com/zkcrypto/bellman) (rust)
+- [libsnark](https://github.com/scipr-lab/libsnark) (c++)
+- [snarkjs](https://github.com/iden3/snarkjs) (javascript)
+- [websnark](https://github.com/iden3/websnark) (wasm)
+- [go-snark](https://github.com/arnaucube/go-snark) (golang) [do not use in production]
+
+## Circuit languages
+| language | snark library with which plugs in |
+|-----|-----|
+| [Zokrates](https://github.com/Zokrates/ZoKrates) | libsnark, bellman |
+| [Snarky](https://github.com/o1-labs/snarky) | libsnark |
+| [circom](https://github.com/iden3/circom) | snarkjs, websnark, bellman |
+| [go-snark-circuit](https://github.com/arnaucube/go-snark) | go-snark |
+
+---
+
+## Utilities (Elliptic curve & Hash functions) inside the zkSNARK
+- we work over $F_r$, where $r=$`21888242871839275222246405745257275088548364400416034343698204186575808495617`
+
+- BabyJubJub
+- Mimc
+- Poseidon
+
+---
+
+##### *Utilities (Elliptic curve & Hash functions) inside the zkSNARK*
+
+### BabyJubJub
+- explaination: https://medium.com/zokrates/efficient-ecc-in-zksnarks-using-zokrates-bd9ae37b8186
+- implementations:
+ - go: https://github.com/iden3/go-iden3-crypto
+ - javascript & circom: https://github.com/iden3/circomlib
+ - rust: https://github.com/arnaucube/babyjubjub-rs
+ - c++: https://github.com/barryWhiteHat/baby_jubjub_ecc
+
+---
+
+##### *Utilities (Elliptic curve & Hash functions) inside the zkSNARK*
+
+### Mimc7
+- explaination: https://eprint.iacr.org/2016/492.pdf
+- implementations in:
+ - go: https://github.com/iden3/go-iden3-crypto
+ - javascript & circom: https://github.com/iden3/circomlib
+ - rust: https://github.com/arnaucube/mimc-rs
+
+---
+
+##### *Utilities (Elliptic curve & Hash functions) inside the zkSNARK*
+
+### Poseidon
+- explaination: https://eprint.iacr.org/2019/458.pdf
+- implementations in:
+ - go: https://github.com/iden3/go-iden3-crypto
+ - javascript & circom: https://github.com/iden3/circomlib
+
+---
+
+# References
+- `Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture`, Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza https://eprint.iacr.org/2013/879.pdf
+- `Pinocchio: Nearly practical verifiable computation`, Bryan Parno, Craig Gentry, Jon Howell, Mariana Raykova https://eprint.iacr.org/2013/279.pdf
+- `On the Size of Pairing-based Non-interactive Arguments`, Jens Groth https://eprint.iacr.org/2016/260.pdf
+- (also all the links through the slides)
+
+---
+
+
+Thank you very much
+
+
+
+
+
+
+
+
+[arnaucube.com](https://arnaucube.com)
+[github.com/arnaucube](https://github.com/arnaucube)
+[twitter.com/arnaucube](https://twitter.com/arnaucube)
+
+
+ 2019-08-20
+
+
+
+[iden3.io](https://iden3.io)
+[github.com/iden3](https://github.com/iden3)
+[twitter.com/identhree](https://twitter.com/identhree)
diff --git a/zksnarks-from-scratch-a-technical-explanation.pdf b/zksnarks-from-scratch-a-technical-explanation.pdf
new file mode 100644
index 0000000..8a11969
Binary files /dev/null and b/zksnarks-from-scratch-a-technical-explanation.pdf differ