diff --git a/easy/src/ec.typ b/easy/src/ec.typ index a18a7cc..20d784b 100644 --- a/easy/src/ec.typ +++ b/easy/src/ec.typ @@ -1,23 +1,23 @@ #import "preamble.typ":* -Before we talk about SNARKs (specifically, PLONK), it helps to separate out an -ingredient that underlies much of programmable cryptography, which is the idea -of a _polynomial commitment_. Specifically, we will talk about the KZG -polynomial commitment, which plays an important role in PLONK (and many other -protocols). For a higher-resolution understanding of KZG, it helps to -understand _elliptic curves_ (especially in the context of _pairings_), which -are ubiquitous in cryptography. If you are uninterested (or experienced) in -mathematical details, you can and should skip elliptic curves and jump to -@kzg. If you are comfortable with black-boxing @kzg, you can even jump +Before we talk about SNARKs (specifically, PLONK), it helps to separate out an +ingredient that underlies much of programmable cryptography, which is the idea +of a _polynomial commitment_. Specifically, we will talk about the KZG +polynomial commitment, which plays an important role in PLONK (and many other +protocols). For a higher-resolution understanding of KZG, it helps to +understand _elliptic curves_ (especially in the context of _pairings_), which +are ubiquitous in cryptography. If you are uninterested (or experienced) in +mathematical details, you can and should skip elliptic curves and jump to +@kzg. If you are comfortable with black-boxing @kzg, you can even jump straight to SNARKs into the next chapter. The roadmap goes roughly as follows: -- In @ec we will define _elliptic curves_ and describe one standard elliptic +- In @ec we will define _elliptic curves_ and describe one standard elliptic curve $E$, the _BN254 curve_, that will be used in these notes. -- In @discretelog we describe the _discrete logarithm assumption_ (@ddh), - which we need to make to provide security to our protocols. As an example, in +- In @discretelog we describe the _discrete logarithm assumption_ (@ddh), + which we need to make to provide security to our protocols. As an example, in @eddsa we describe how @ddh can be used to construct a signature scheme, namely #cite("https://en.wikipedia.org/wiki/EdDSA", "EdDSA"). @@ -258,11 +258,11 @@ we will rely on the so-called _discrete logarithm_ assumption. Let $E$ be the BN254 curve (or another standardized curve). Given arbitrary nonzero $g, g' in E$, the _discrete logarithm problem_ asks you - to find an integer $n$ such that $n dot g = g'$. + to find an integer $n$ such that $n dot g = g'$. Experience suggests that the discrete logarithm problem is hard: in general, we don't know a fast algorithm to solve it. - The _discrete logarithm assumption_ + The _discrete logarithm assumption_ says that no such algorithm exists. ] diff --git a/easy/src/fhe0.typ b/easy/src/fhe0.typ index bbadf9c..d797a7b 100644 --- a/easy/src/fhe0.typ +++ b/easy/src/fhe0.typ @@ -9,7 +9,7 @@ Actually, Alice wants Bob to compute $f(x)$ -- but she doesn't want to tell him $x$. What Alice wants is a _fully homomorphic encryption (FHE)_ protocol, meaning: 1. Alice encrypts $x$ and sends Bob $Enc (x)$. 2. Bob then "applies $f$ to the ciphertext" and obtains $Enc (f(x))$, sending it to Alice. -3. Alice decrypts $Enc (f(x))$ to learn $f(x)$. +3. Alice decrypts $Enc (f(x))$ to learn $f(x)$. _Levelled FHE_ is a weaker version of FHE. Like FHE, levelled FHE lets you perform operations on encrypted data. But unlike FHE, there @@ -27,7 +27,7 @@ operations you can do before the error gets too big. As a sort of silly example, imagine your message is a whole number between 0 and 10 (so it’s one of 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10), and your "encryption scheme" encrypts the message as a real number that is -very close to the message, and decrypts a real number by "round to the nearest integer." So, the message 2 might be encrypted as 1.999832. +very close to the message, and decrypts a real number by "round to the nearest integer." So, the message 2 might be encrypted as 1.999832. (You might be thinking: This is some pretty terrible cryptography, because the message isn’t secure. Anyone can figure out how to round a diff --git a/easy/src/fhe2.typ b/easy/src/fhe2.typ index 987c020..5f2616a 100644 --- a/easy/src/fhe2.typ +++ b/easy/src/fhe2.typ @@ -26,21 +26,21 @@ set" will be exactly the public key. align: (auto,), table.header([Public Key],), table.hline(), - [(1, 0, 1, 7) : 2], - [(5, 8, 4, 10) : 2], - [(7, 7, 8, 5) : 3], - [(5, 1, 10, 6) : 10], - [(8, 0, 2, 4) : 9], - [(9, 3, 0, 6) : 9], - [(0, 6, 1, 6) : 9], - [(0, 4, 9, 7) : 5], + [(1, 0, 1, 7) : 2], + [(5, 8, 4, 10) : 2], + [(7, 7, 8, 5) : 3], + [(5, 1, 10, 6) : 10], + [(8, 0, 2, 4) : 9], + [(9, 3, 0, 6) : 9], + [(0, 6, 1, 6) : 9], + [(0, 4, 9, 7) : 5], [(10, 7, 4, 10) : 10], - [(5, 5, 10, 6) : 9], - [(10, 7, 3, 1) : 9], - [(0, 2, 5, 5) : 6], - [(9, 10, 2, 1) : 3], + [(5, 5, 10, 6) : 9], + [(10, 7, 3, 1) : 9], + [(0, 2, 5, 5) : 6], + [(9, 10, 2, 1) : 3], [(3, 7, 2, 1) : 6], - [(2, 3, 4, 5) : 3], + [(2, 3, 4, 5) : 3], [(2, 1, 6, 9) : 3], )] , kind: table @@ -147,7 +147,7 @@ computes $ upright(bold(x)) dot.op upright(bold(a)) = 4 . $ Plugging in $y = 1$, we see that $ 4 + epsilon.alt = 1 + m . $ Now it’s a simple "rounding" problem. We know that $epsilon.alt$ is -small and positive, so $1 + m$ is either $4$ or … a little more. +small and positive, so $1 + m$ is either $4$ or … a little more. (In fact, it’s one of $4 , 5 , 6 , 7 , 8$.) On the other hand, since $m$ is 0 or 5, $1 + m$ had better be 1 or 6, so the only possibility is that $m = 5$ (so $1+m = 6$). @@ -161,7 +161,7 @@ do FHE, we’re going to want to take $q$ pretty big, so you should imagine that $q approx 2^(sqrt(n))$. For security, instead of adding $4$ rows of the public key, we want to add -at least $log (q^n) = n log q$ rows. To be safe, maybe a little bigger, say +at least $log (q^n) = n log q$ rows. To be safe, maybe a little bigger, say $m = 2 n log q$ (of course, for this to work, the public key has to have at least $m$ rows). The encryption algorithm will be "select some subset of the rows at random, diff --git a/easy/src/fhe3.typ b/easy/src/fhe3.typ index c2475e8..887b5be 100644 --- a/easy/src/fhe3.typ +++ b/easy/src/fhe3.typ @@ -26,7 +26,7 @@ modulo $q$ – but we’ll also allow the calculations to have a small $q$. As before, our #emph[secret key] will be a vector of length $n$: -$ upright(bold(v)) = (v_1, dots, v_n) in (ZZ \/ q ZZ)^n. $ +$ upright(bold(v)) = (v_1, dots, v_n) in (ZZ \/ q ZZ)^n. $ Suppose we want to encode a message $mu$ that’s just a single bit, let’s say $mu in { 0 , 1 }$. Our ciphertext will be a square $n$-by-$n$ matrix $C$ @@ -128,7 +128,7 @@ $(1 , 0 , 0 , 1)$ is the binary expansion of $9$. #problem[ How would you flatten a different vector, like -$ upright(bold(x)) = (9 , 3 , 1 , 4) ? $ +$ upright(bold(x)) = (9 , 3 , 1 , 4) ? $ As a hint, remember we’re working with numbers modulo 11: so if you come across a number that’s bigger than 11 in your calculation, it’s safe to reduce it mod 11. diff --git a/easy/src/kzg.typ b/easy/src/kzg.typ index 7a55ee2..fbe9ef4 100644 --- a/easy/src/kzg.typ +++ b/easy/src/kzg.typ @@ -42,7 +42,7 @@ Then anyone in the world can use the resulting sequence for KZG commitments. this is a case of the discrete logarithm problem. You can make the protocol somewhat more secure by involving several different trusted parties. - The first party chooses a random $s_1$, computes $[s_1^0], ..., [s_1^M]$, + The first party chooses a random $s_1$, computes $[s_1^0], ..., [s_1^M]$, and then discards $s_1$. The second party chooses $s_2$ and computes $[(s_1 s_2)^0], ..., [(s_1 s_2)^M]$. @@ -174,7 +174,7 @@ To be fully explicit, here is the algorithm: to prove to Victor the values of $F$. So for example, if $F$ is a product of two polynomials - $F = F_1 F_2$, + $F = F_1 F_2$, and Peggy has already sent commitments to $F_1$ and $F_2$, then there is no need for Peggy to commit to $F$. diff --git a/easy/src/plonk.typ b/easy/src/plonk.typ index 19867f4..eb60eb3 100644 --- a/easy/src/plonk.typ +++ b/easy/src/plonk.typ @@ -13,8 +13,8 @@ perform proofs for arbitrary functions. That means we need a "programming language" that we'll write our function in. For PLONK, the choice that's used is: *systems of quadratic equations over $FF_q$*. In other words, PLONK is going to -give us the ability to prove that we have solutions to a system of quadratic -equations. +give us the ability to prove that we have solutions to a system of quadratic +equations. #situation[ Suppose we have a system of $m$ equations in $k$ variables $x_1, dots, x_k$: @@ -38,15 +38,15 @@ equations. This leads to the natural question of how a function like SHA-256 can be encoded into a system of quadratic equations. This process of encoding a problem into algebra is called _arithmetization_. It turns out that quadratic equations -over $FF_q$, viewed as an NP problem called Quad-SAT, is _NP-complete_; -in other words, any NP problem can be rewritten as a system of quadratic equations. +over $FF_q$, viewed as an NP problem called Quad-SAT, is _NP-complete_; +in other words, any NP problem can be rewritten as a system of quadratic equations. If you are not familiar with this concept, the upshot is that Quad-SAT being NP-complete means it can serve as a reasonable arithmetization that can express most reasonable (NP) problems. #remark([Quad-SAT is NP-complete])[ - We assume knowledge of 3-SAT and it being NP-complete. - The following example instance illustrates how to convert + We assume knowledge of 3-SAT and it being NP-complete. + The following example instance illustrates how to convert any instance of 3-SAT into a Quad-SAT problem: $ x_i^2 &= x_i #h(1em) forall 1 <= i <= 1000 & \