From 7311336aae878312e7e97e23f0069018660ec489 Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Tue, 11 Jun 2024 10:33:13 -0400 Subject: [PATCH] style: remove trailing whitespace --- easy/src/fhe0.typ | 8 +-- easy/src/fhe3.typ | 18 +++--- easy/src/lwe.typ | 18 +++--- easy/src/mpc.typ | 46 +++++++------- easy/src/mpc2.typ | 32 +++++----- easy/src/ot.typ | 144 +++++++++++++++++++++---------------------- easy/src/pair.typ | 4 +- easy/src/plonk.typ | 6 +- easy/src/zkintro.typ | 4 +- 9 files changed, 140 insertions(+), 140 deletions(-) diff --git a/easy/src/fhe0.typ b/easy/src/fhe0.typ index f672b31..a789e6b 100644 --- a/easy/src/fhe0.typ +++ b/easy/src/fhe0.typ @@ -5,7 +5,7 @@ Alice has a secret $x$, and Bob has a function $f$. They want to compute $f(x)$. -Actually, Alice wants Bob to compute $f(x)$ -- but +Actually, Alice wants Bob to compute $f(x)$ -- but she doesn't want to tell him $x$. Alice wants to encrypt $x$ and send Bob $Enc (x)$. @@ -13,7 +13,7 @@ Then Bob is going to "apply $f$ to the ciphertext", to turn $Enc (x)$ into $Enc (f(x))$. Finally, Bob sends $Enc (f(x))$ back, and Alice decrypts it to learn $f(x)$. - + This is fully homomorphic encryption (FHE). Levelled FHE is a sort of weaker version of FHE. Like FHE, levelled FHE @@ -52,14 +52,14 @@ won’t give the right answer anymore. But as long as you’re careful not to go over the error limit, you can add ciphertexts with confidence. -In fact, for our levelled FHE protocol, our message will be a bit: +In fact, for our levelled FHE protocol, our message will be a bit: either 0 or 1; our operations will be the logic gates AND and NOT. Any logic circuit can be built out of AND and NOT gates, so we'll be able to perform arbitrary calculations within the FHE encryption. -Our protocol uses a cryptosystem built +Our protocol uses a cryptosystem built from a problem called "learning with errors." "Learning with errors" is kind of a strange name; I'd call it "approximate linear algebra modulo $q$." diff --git a/easy/src/fhe3.typ b/easy/src/fhe3.typ index 24561fe..b78a846 100644 --- a/easy/src/fhe3.typ +++ b/easy/src/fhe3.typ @@ -5,13 +5,13 @@ Now we want to turn the public-key encryption from @lwe-crypto into a levelled FHE scheme. -In other words: +In other words: We want to be able to encrypt bits (0s and 1s) and operate on them with AND and NOT gates. -It might help you to imagine that, instead of AND and NOT, +It might help you to imagine that, instead of AND and NOT, the operations we want to encrypt are addition and multiplication. -If $x$ and $y$ are bits, then +If $x$ and $y$ are bits, then NOT $x$ is just $1 - x$, and $x$ AND $y$ is just $x y$. But it's easier to do algebra with $+$ and $*$. @@ -23,7 +23,7 @@ modulo $q$ – but we’ll also allow the calculations to have a small "error" $epsilon.alt$, which will typically be much, much smaller than $q$. -Here’s the new idea. +Here’s the new idea. Our #emph[secret key] will be a vector $ upright(bold(v)) = (v_1, dots, v_n) in (ZZ \/ q ZZ)^n $ – a vector of length $n$, where the entries are integers modulo $q$. Suppose @@ -36,7 +36,7 @@ $C upright(bold(v))$, and determine whether it is closer to $0$ or to $v_i$. With a bit of effort, it’s possible to make this into a public-key -cryptosystem. Just like in @lwe-crypto, +cryptosystem. Just like in @lwe-crypto, the main idea is to release a table of vectors $upright(bold(x))$ such that @@ -106,7 +106,7 @@ value of $a_1$. Now suppose I give you the vector $ upright(bold(x)) = (9 , 0 , 0 , 0) . $ I ask you for another vector $ "Flatten"(upright(bold(x))) = upright(bold(x)) prime , $ where -$upright(bold(x)) prime$ has to have the following two properties: +$upright(bold(x)) prime$ has to have the following two properties: - $upright(bold(x)) prime dot.op upright(bold(v)) = upright(bold(x)) dot.op upright(bold(v))$, and - All the entries of $upright(bold(x)) prime$ are either 0 or 1. @@ -129,7 +129,7 @@ Similarly, if you know $upright(bold(v))$ has the form $ upright(bold(v)) = (a_1 , 2 a_1 , 4 a_1 , dots.h , 2^k a_1 , a_2 , 2 a_2 , 4 a_2 , dots.h , 2^k a_2 , dots.h , a_r , 2 a_r , 4 a_r , dots.h , 2^k a_r) , $ and you are given some matrix $C$ with coefficients in $ZZ \/ q ZZ$, then you can compute another matrix $"Flatten"(C)$ -such that: +such that: - $"Flatten"(C) upright(bold(v)) = C upright(bold(v))$, and - All the entries of $"Flatten"(C)$ are either 0 or 1. @@ -194,12 +194,12 @@ This gives us a #emph[levelled] fully homomorphic encryption protocol: it lets us evaluate arbitrary circuits on encrypted data, as long as those circuits have bounded depth. If we need to evaluate a bigger circuit, we have two options. -+ Increase the value of $q$. ++ Increase the value of $q$. Of course, the cost of the computations increases with $q$. + Use some technique to "reset" the error and start anew, as if with a freshly encrypted ciphertext. - This approach is called "bootstrapping" and it incurs some hefty + This approach is called "bootstrapping" and it incurs some hefty computational costs. But for very, very large circuits, it's the only viable option. diff --git a/easy/src/lwe.typ b/easy/src/lwe.typ index e553910..d891f85 100644 --- a/easy/src/lwe.typ +++ b/easy/src/lwe.typ @@ -4,7 +4,7 @@ Many cryptographic protocols rely on some sort of "hard problem" --- a computationally infeasible challenge +-- a computationally infeasible challenge whose difficulty makes the protocol secure. It is hard to factor a composite number (like $6177$) into prime factors ($6177 = 71*87$); @@ -17,7 +17,7 @@ KZG polynomial commitments (@kzg), and so forth. Our protocol for levelled FHE relies on a different hard problem. The problem is to solve systems of linear equations. -Except the equations are only approximately true -- +Except the equations are only approximately true -- they permit a small "error" -- and instead of solving for rational or real numbers, you're solving for integers modulo $q$. @@ -71,28 +71,28 @@ $(a_1 , dots.h , a_4)$. #solution[ We start with some helpful notation. Define an #strong[information -vector] +vector] $ (x_1 , x_2 , x_3 , x_4 lr(|y|) S), $ where $S subset F_11$, to -mean the statement -#quote[$sum a_i x_i = y + s$, where $s in S$.] +mean the statement +#quote[$sum a_i x_i = y + s$, where $s in S$.] In particular, a given purported approximation $ (x_1 , x_2 , x_3 , x_4) : y -$ +$ in the LWE protocol corresponds to the -information vector +information vector $ (x_1 , x_2 , x_3 , x_4 lr(|y|) { 0 , - 1 }). -$ +$ The benefit of this notion is that we can take linear combinations of them. Specifically, -#proposition[ +#proposition[ If $(X_1 lr(|y_1|) S_1)$ and $(X_2 lr(|y_2|) S_2)$ are information vectors (where $X_i$ are vectors), then diff --git a/easy/src/mpc.typ b/easy/src/mpc.typ index 16c79f9..de8032a 100644 --- a/easy/src/mpc.typ +++ b/easy/src/mpc.typ @@ -35,7 +35,7 @@ Here is our problem setting, slightly more formally: == The solution (an outline) Very briefly: -- Alice constructs a "garbled circuit" +- Alice constructs a "garbled circuit" that takes in the value $b$ (whatever it is) and spits out $f(a, b)$. @@ -44,7 +44,7 @@ Very briefly: a secret password corresponding to his input bits. (or: that Bob can only evaluate once...) -- Alice uses "oblivious transfer" +- Alice uses "oblivious transfer" to send Bob the password for his input. Bob doesn't learn the passwords for any other inputs, @@ -52,11 +52,11 @@ Very briefly: #todo[ Ask Gub to paraphrase, he writes well -] +] In slightly more detail: -Whatever the function $f$ is, +Whatever the function $f$ is, we'll assume that it takes $m+n$ bits of input $a_1, dots, a_m$ and $b_1, dots, b_n$, and that it's computed by some sort of circuit @@ -65,7 +65,7 @@ made of AND, OR and NOT gates. Alice's first task is to "plug her own inputs into this circuit $f$." The result will be a new circuit (you might call it $f_a$) -that has just $n$ input slots +that has just $n$ input slots for Bob's $n$ bits $b_1, dots, b_n$. And then Alice is going to "garble" the circuit $f_a$. @@ -74,10 +74,10 @@ He'll only be able to plug his own input $(b_1, dots, b_n)$ into the circuit. What stops Bob from plugging other inputs in as well? -A garbled circuit will require a "password" +A garbled circuit will require a "password" for each input Bob wants to plug in -- a different password for every possible input. -If Bob has the password for $(b_1, dots, b_n)$, +If Bob has the password for $(b_1, dots, b_n)$, he can learn $f_a(b_1, dots, b_n) = f(a, b)$ -- but he won't learn anything else about how the circuit works. @@ -98,7 +98,7 @@ except its functionality is hidden. What does that mean? Let's say the gate has two input bits, -so there are four possible inputs to the gate: +so there are four possible inputs to the gate: $(0, 0), (0, 1), (1, 0), (1, 1)$. For each of those four inputs $(x, y)$, there is a secret password $P_(x, y)$. @@ -112,7 +112,7 @@ Choose a symmetric-key "when you think of plain-vanilla encryption: " + "You use a secret key $K$ to encrypt a message $m$, " + "and then you use the same secret key $K$ to decrypt it.") -] +] encryption scheme $Enc$ [#footnote("We'll talk later about what sort of " + "encryption scheme is suitable for this...")] @@ -147,10 +147,10 @@ We'll need to make two changes to the protocol. 1. To chain garbled gates together, we need to modify the output of each gate: In addition to outputting the bit $z = G_i (x, y)$, - the $i$-th gate $G_i$ + the $i$-th gate $G_i$ will also output a password $P_z$ that Bob can use at the next step. - Now Bob has one bit coming in for the left-hand input $x$, + Now Bob has one bit coming in for the left-hand input $x$, and it came with some password $P_x^(text("left"))$ -- and then another bit coming in for $y$, that came with some password $P_y^(text("right"))$. @@ -164,13 +164,13 @@ We'll need to make two changes to the protocol. even the single bit he gets as output. This is an easy fix: - Instead of having the gate output + Instead of having the gate output both the bit $z$ and the password $P_z$, we'll just have the gate output the password $P_z$. But now how does Bob know what values to feed into the next gate? - The left-hand column of the "gate table" - needs to be indexed by the passwords + The left-hand column of the "gate table" + needs to be indexed by the passwords $P_x^(text("left"))$ and $P_y^(text("right"))$, not by the bits $(x, y)$. But we don't want Bob to learn the other passwords from the table! @@ -182,7 +182,7 @@ We'll need to make two changes to the protocol. Of course, the solution is to use a hash function! So here is the new version of our garbled gate. - For simplicity, I'll assume it's an AND gate -- + For simplicity, I'll assume it's an AND gate -- so the outputs will be (the passwords encoding) 0, 0, 0, 1. #table( columns: 2, @@ -198,22 +198,22 @@ Let's play through one round of Bob's gate-using protocol. 0. Suppose Bob's input bits are 0 (on the left) and 1 (on the right). Bob doesn't know he has 0 and 1 (but we do!). - Bob knows his left password is some value + Bob knows his left password is some value $ P_0^(text("left")), $ - and his right password is some other value + and his right password is some other value $ P_1^(text("right")). $ 1. Bob takes the two passwords, concatenates them, and computes a hash. - Now Bob has + Now Bob has $ sha(P_0^(text("left")), P_1^(text("right"))). $ -2. Bob finds the row of the table indexed by +2. Bob finds the row of the table indexed by $sha(P_0^(text("left")), P_1^(text("right")))$, and he uses it to look up $ @@ -230,7 +230,7 @@ Let's play through one round of Bob's gate-using protocol. 4. Now Bob has the password for the bit 0, to feed into the next gate -- but he doesn't know his bit is 0. -So Bob is exactly where he started: +So Bob is exactly where he started: he knows the password for his bit, but he doesn't know his bit. So we can chain together as many of these garbled gates as we like to make a full garbled circuit. @@ -243,13 +243,13 @@ How? Easy! The final output gates are different from the intermediate gates. -Instead of outputting a password, +Instead of outputting a password, they will just output the resulting bit in plain text. == How the circuit starts This is trickier. -At the beginning of the computation, +At the beginning of the computation, Bob needs to learn the passwords for all of his input bits. Let's just tackle the problem for a single bit. @@ -259,7 +259,7 @@ Let's just tackle the problem for a single bit. - Bob does not want Alice to learn the value of $b$. - Alice does not want Bob to learn the other password. -Alice sends the password to Bob +Alice sends the password to Bob using a protocol called oblivious transfer, which we'll see in @ot. diff --git a/easy/src/mpc2.typ b/easy/src/mpc2.typ index f910dd1..121449f 100644 --- a/easy/src/mpc2.typ +++ b/easy/src/mpc2.typ @@ -41,7 +41,7 @@ except its functionality is hidden. What does that mean? Let's say the gate has two input bits, -so there are four possible inputs to the gate: +so there are four possible inputs to the gate: $(0, 0), (0, 1), (1, 0), (1, 1)$. For each of those four inputs $(x, y)$, there is a secret password $P_(x, y)$. @@ -55,7 +55,7 @@ Choose a symmetric-key "when you think of plain-vanilla encryption: " + "You use a secret key $K$ to encrypt a message $m$, " + "and then you use the same secret key $K$ to decrypt it.") -] +] encryption scheme $Enc$ [#footnote("We'll talk later about what sort of " + "encryption scheme is suitable for this...")] @@ -90,11 +90,11 @@ We'll need to make two changes to the protocol. 1. To chain garbled gates together, we need to modify the output of each gate: In addition to outputting the bit $z = G_i (x, y)$, - the $i$-th gate $G_i$ + the $i$-th gate $G_i$ will also output a password $P_z$ that Bob can use at the next step. #todo[Introduce Bob] - Now Bob has one bit coming in for the left-hand input $x$, + Now Bob has one bit coming in for the left-hand input $x$, and it came with some password $P_x^(text("left"))$ -- and then another bit coming in for $y$, that came with some password $P_y^(text("right"))$. @@ -108,13 +108,13 @@ We'll need to make two changes to the protocol. even the single bit he gets as output. This is an easy fix: - Instead of having the gate output + Instead of having the gate output both the bit $z$ and the password $P_z$, we'll just have the gate output the password $P_z$. But now how does Bob know what values to feed into the next gate? - The left-hand column of the "gate table" - needs to be indexed by the passwords + The left-hand column of the "gate table" + needs to be indexed by the passwords $P_x^(text("left"))$ and $P_y^(text("right"))$, not by the bits $(x, y)$. But we don't want Bob to learn the other passwords from the table! @@ -126,7 +126,7 @@ We'll need to make two changes to the protocol. Of course, the solution is to use a hash function! So here is the new version of our garbled gate. - For simplicity, I'll assume it's an AND gate -- + For simplicity, I'll assume it's an AND gate -- so the outputs will be (the passwords encoding) 0, 0, 0, 1. #table( columns: 2, @@ -142,22 +142,22 @@ Let's play through one round of Bob's gate-using protocol. 0. Suppose Bob's input bits are 0 (on the left) and 1 (on the right). Bob doesn't know he has 0 and 1 (but we do!). - Bob knows his left password is some value + Bob knows his left password is some value $ P_0^(text("left")), $ - and his right password is some other value + and his right password is some other value $ P_1^(text("right")). $ 1. Bob takes the two passwords, concatenates them, and computes a hash. - Now Bob has + Now Bob has $ sha(P_0^(text("left")), P_1^(text("right"))). $ -2. Bob finds the row of the table indexed by +2. Bob finds the row of the table indexed by $sha(P_0^(text("left")), P_1^(text("right")))$, and he uses it to look up $ @@ -174,7 +174,7 @@ Let's play through one round of Bob's gate-using protocol. 4. Now Bob has the password for the bit 0, to feed into the next gate -- but he doesn't know his bit is 0. -So Bob is exactly where he started: +So Bob is exactly where he started: he knows the password for his bit, but he doesn't know his bit. So we can chain together as many of these garbled gates as we like to make a full garbled circuit. @@ -187,13 +187,13 @@ How? Easy! The final output gates are different from the intermediate gates. -Instead of outputting a password, +Instead of outputting a password, they will just output the resulting bit in plain text. == How the circuit starts This is trickier. -At the beginning of the computation, +At the beginning of the computation, Bob needs to learn the passwords for all of his input bits. Let's just tackle the problem for a single bit. @@ -204,7 +204,7 @@ Let's just tackle the problem for a single bit. - Bob does not want Alice to learn the value of $b$. - Alice does not want Bob to learn the other password. -Alice sends the password to Bob +Alice sends the password to Bob using a protocol called oblivious transfer @ot. diff --git a/easy/src/ot.typ b/easy/src/ot.typ index 3d7fb11..f703229 100644 --- a/easy/src/ot.typ +++ b/easy/src/ot.typ @@ -3,57 +3,57 @@ = Oblivious Transfer -Alice has $n$ messages $x_1, dots, x_n$. -Bob wants to request the $i$-th message, -without letting Alice learn anything about the value of $i$. -Alice wants to send Bob $x_i$, -without letting him learn anything about the other $n-1$ messages. -This process is called "oblivious transfer": -Alice transfers a single message to Bob, +Alice has $n$ messages $x_1, dots, x_n$. +Bob wants to request the $i$-th message, +without letting Alice learn anything about the value of $i$. +Alice wants to send Bob $x_i$, +without letting him learn anything about the other $n-1$ messages. +This process is called "oblivious transfer": +Alice transfers a single message to Bob, but she remains oblivious as to which message she has transferred. We'll see two simple protocols to achieve this. -(In fact, for two-party computation, +(In fact, for two-party computation, we only "1-of-2 oblivious transfer": -Alice has $x_1$ and $x_2$, and she wants to send one of +Alice has $x_1$ and $x_2$, and she wants to send one of those two to Bob. But 1-of-$n$ isn't any harder, so we'll do 1-of-$n$.) == Commutative encryption -Let's imagine that Alice and Bob +Let's imagine that Alice and Bob have access to some encryption scheme that is _commutative_: $ Dec_{B}( Dec_{A} - ( Enc_{B} - ( Enc_{A}(x) ) ) ) + ( Enc_{B} + ( Enc_{A}(x) ) ) ) = x. $ -In other words, if Alice encrypts a message, -and Bob applies a second-layer of encryption to the encrypted message, -it doesn't matter which order Alice and Bob decrypt the message in -- +In other words, if Alice encrypts a message, +and Bob applies a second-layer of encryption to the encrypted message, +it doesn't matter which order Alice and Bob decrypt the message in -- they will still get the original message back. -A metaphor for commutative encryption -is a box that's locked with two padlocks. -Alice puts a message inside the box, -lock it with her lock, and ship it to Bob. -Bob puts his own lock back on the box and ships it back to Alice. -What's special about commutative encryption -is that Bob's lock doesn't block Alice from unlocking her own -- -so Alice can remove her lock and send it back to Bob, +A metaphor for commutative encryption +is a box that's locked with two padlocks. +Alice puts a message inside the box, +lock it with her lock, and ship it to Bob. +Bob puts his own lock back on the box and ships it back to Alice. +What's special about commutative encryption +is that Bob's lock doesn't block Alice from unlocking her own -- +so Alice can remove her lock and send it back to Bob, and then Bob removes his lock and recovers the message. -Mathematically, you can get commutative encryption +Mathematically, you can get commutative encryption by working in a finite group (for example $ZZ_p^*$, or an elliptic curve). -Alice's secret key is an integer $a$; -she encrypts a message $g$ by raising it to the $a$-th power, +Alice's secret key is an integer $a$; +she encrypts a message $g$ by raising it to the $a$-th power, and she sends Bob $g^a$. -Bob encrypts again with his own secret key $b$, +Bob encrypts again with his own secret key $b$, and he sends $(g^a)^b = g^{a b}$ back to Alice. Now Alice removes her lock by taking an $a$-th root. The result is $g^b$, which she sends back to Bob. And Bob takes another $b$-th root, recovering $g$. @@ -69,22 +69,22 @@ $ But crucially, Alice sends the ciphertexts in order, so Bob knows which is which. -At this point, Bob can't read any of the messages, -because he doesn't know the keys. -No problem! -Bob just picks out the $i$-th ciphertext $Enc_{a}(x_i)$, -adds his own layer of encryption onto it, +At this point, Bob can't read any of the messages, +because he doesn't know the keys. +No problem! +Bob just picks out the $i$-th ciphertext $Enc_{a}(x_i)$, +adds his own layer of encryption onto it, and sends the resulting doubly-encoded message back to Alice: $ Enc_{b}(Enc_{a}(x_i)). $ -Alice doesn't know Bob's key $b$, -so she can't learn anything about the message he encrypted -- -even though it originally came from her. -Nonetheless she can apply her own decryption method -$Dec_a$ to it. -Since the encryption scheme is commutative, +Alice doesn't know Bob's key $b$, +so she can't learn anything about the message he encrypted -- +even though it originally came from her. +Nonetheless she can apply her own decryption method +$Dec_a$ to it. +Since the encryption scheme is commutative, the result of Alice's decryption is simply $ Enc_{b}(x_i), @@ -95,12 +95,12 @@ And Bob decrypts the message to learn $x_i$. == OT in one step -The protocol above required one and a half rounds of communication: +The protocol above required one and a half rounds of communication: Alice sent two messages to Bob, and Bob sent one message back to Alice. We can do better, using public-key cryptography. -Let's start with a simplified protocol that is not quite secure. +Let's start with a simplified protocol that is not quite secure. The idea is for Bob to send Alice $n$ keys $ b_1, dots, b_n. @@ -115,45 +115,45 @@ $ Now Bob uses the private key for $b_i$ to decrypt $x_i$, and he's done. -Is Bob happy with this protocol? Yes. -Alice has no way of learning the value of $i$, -as long as she can't distinguish a true public key +Is Bob happy with this protocol? Yes. +Alice has no way of learning the value of $i$, +as long as she can't distinguish a true public key from a random fake key (which is true of public-key schemes in practice). -But is Alice happy with it? Not so much. -A cheating Bob could send $n$ different public keys, -and Alice has no way to detect it -- -like we just said, Alice can't tell random garbage from a true public key! +But is Alice happy with it? Not so much. +A cheating Bob could send $n$ different public keys, +and Alice has no way to detect it -- +like we just said, Alice can't tell random garbage from a true public key! And then Bob would be able to decrypt all $n$ messages $x_1, dots, x_n$. -But there's a simple trick to fix it. -Bob chooses some "verifiably random" value $r$ -- -to fix ideas, we could agree to use $r = sha(1)$. -Then we require that the numbers $b_1, dots, b_n$ +But there's a simple trick to fix it. +Bob chooses some "verifiably random" value $r$ -- +to fix ideas, we could agree to use $r = sha(1)$. +Then we require that the numbers $b_1, dots, b_n$ form an arithmetic progression with common difference $r$. - Bob chooses $i$, computes a public-private key pair, - and sets $b_i$ equal to that key. - Then all the other terms $b_1, dots, b_n$ - are determined by the arithmetic progression requirement $b_j = b_i + (j-i)r$. - (Or if the keys are elements of a group in multiplicative notation, + Bob chooses $i$, computes a public-private key pair, + and sets $b_i$ equal to that key. + Then all the other terms $b_1, dots, b_n$ + are determined by the arithmetic progression requirement $b_j = b_i + (j-i)r$. + (Or if the keys are elements of a group in multiplicative notation, we could write this as $b_j = r^{j-i} * b_i$.) -Is this secure? -If we think of the hash function as a random-number generator, -then all $n-1$ "garbage keys" are effectively random values. -So now the question is: -Can Bob compute a private key for a given (randomly generated) public key? -It's a standard assumption in public-key cryptography that Bob can't do this: -there's no algorithm that reads in a public key and spits out the corresponding private key. -(Otherwise, the whole enterprise is doomed.) +Is this secure? +If we think of the hash function as a random-number generator, +then all $n-1$ "garbage keys" are effectively random values. +So now the question is: +Can Bob compute a private key for a given (randomly generated) public key? +It's a standard assumption in public-key cryptography that Bob can't do this: +there's no algorithm that reads in a public key and spits out the corresponding private key. +(Otherwise, the whole enterprise is doomed.) So Alice is guaranteed that Bob only knows how to decrypt (at most) one message. -In fact, some public-key cryptosystems (like ElGamal) -have a sort of "homomorphic" property: -If you know the private keys for to two different public keys $b_1$ and $b_2$, -then you can compute the private key for the public key $b_2 b_1^{-1}$. -(In ElGamal, this is true because the private key is just a discrete logarithm.) -So, if Bob could dishonestly decrypt two of Alice's messages, -he could compute the private key for the public key $r$. -But $r$ is verifiably random, +In fact, some public-key cryptosystems (like ElGamal) +have a sort of "homomorphic" property: +If you know the private keys for to two different public keys $b_1$ and $b_2$, +then you can compute the private key for the public key $b_2 b_1^{-1}$. +(In ElGamal, this is true because the private key is just a discrete logarithm.) +So, if Bob could dishonestly decrypt two of Alice's messages, +he could compute the private key for the public key $r$. +But $r$ is verifiably random, and it's very hard (we assume) for Bob to find a private key for a random public key. diff --git a/easy/src/pair.typ b/easy/src/pair.typ index dbc0462..d5aab3c 100644 --- a/easy/src/pair.typ +++ b/easy/src/pair.typ @@ -64,12 +64,12 @@ So this gives us a way to _verify_ two-by-two multiplication. where Peggy has sent Victor elliptic curve points [x] and [y]. To do this, Peggy additionally sends to Victor $[x^2]$ and $[x^3]$. - Given $[x]$, $[x^2]$, $[x^3]$, and $[y]$, + Given $[x]$, $[x^2]$, $[x^3]$, and $[y]$, Victor verifies that: - $pair([x^2], 1) = pair([x], [x]) $ - $pair([x^3], 1) = pair([x^2], [x]) $ - $[y] = [x^3] + 2 [1]$. - + The process of verifying this sort of identity is quite general: The prover sends intermediate values as needed so that the verifier can verify the claim using only pairings and linearity. diff --git a/easy/src/plonk.typ b/easy/src/plonk.typ index df32b35..1a78ad1 100644 --- a/easy/src/plonk.typ +++ b/easy/src/plonk.typ @@ -476,7 +476,7 @@ To summarize, the copy-check goes as follows: == Public and private witnesses -#todo[warning: $A$, $B$, $C$ should not be the lowest degree interpolations, imo +#todo[warning: $A$, $B$, $C$ should not be the lowest degree interpolations, imo AV: why not? I think it's fine if they are] The last thing to be done is to reveal the value of public witnesses, @@ -484,12 +484,12 @@ so the prover can convince the verifier that those values are correct. This is simply an application of @root-check. Let's say the public witnesses are the values $a_i$, for all $i$ in some set $S$. (If some of the $b$'s and $c$'s are also public, we'll just do the same thing for them.) -The prover can interpolate another polynomial, $A^"public"$, +The prover can interpolate another polynomial, $A^"public"$, such that $A^"public"(omega^i) = a_i$ if $i in S$, and $A^"public"(omega^i) = 0$ if $i in.not S$. Actually, both the prover and the verifier can compute $A^"public"$, since all the values $a_i$ are publicly known! -Now the prover runs @root-check to prove that $A - A^"public"$ +Now the prover runs @root-check to prove that $A - A^"public"$ vanishes on $S$. (And similarly for $B$ and $C$, if needed.) And we're done. diff --git a/easy/src/zkintro.typ b/easy/src/zkintro.typ index 6468529..532048f 100644 --- a/easy/src/zkintro.typ +++ b/easy/src/zkintro.typ @@ -4,12 +4,12 @@ Peggy has done some very difficult calculation. She wants to prove to Victor that she did it. -Victor wants to check that Peggy did it, but he +Victor wants to check that Peggy did it, but he is too lazy to redo the whole calculation himself. - Maybe Peggy wants to keep part of the calculation secret. Maybe her calculation was "find a solution to this puzzle," - and she wants to prove that she found a solution + and she wants to prove that she found a solution without saying what the solution is. - Maybe it's just a really long, annoying calculation, and Victor doesn't have the energy to check it all line-by-line.