diff --git a/.gitignore b/.gitignore index db4561e..020fb8e 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,8 @@ docs/_build/ # PyBuilder target/ + + +# shamir specific + +env/ diff --git a/README.md b/README.md index f0afc3c..3f6619f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ itself is rendered using [reveal.js](http://lab.hakim.se/reveal-js/). #### stating the presentation `make serve` should work! Then you will need to browse to -http://localhost:2000/cryptographie_visuelle.slides.html to see the presentation +http://localhost:2000/presentation.slides.html to see the presentation in a web browser. #### hacking the presentation diff --git a/makefile b/makefile index bccae40..0312c4b 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ pres: - env/bin/ipython3 nbconvert cryptographie_visuelle.ipynb --to slides --template output_toggle + env/bin/ipython3 nbconvert presentation.ipynb --to slides --template output_toggle test: env/bin/nosetests @@ -8,7 +8,7 @@ ipython: env/bin/ipython3 notebook serve: reveal.js - echo "browse to http://localhost:2000/cryptographie_visuelle.slides.html" + echo "browse to http://localhost:2000/presentation.slides.html" env/bin/python -m http.server 2000 env: reveal.js diff --git a/cryptographie_visuelle.slides.html b/presentation.html similarity index 100% rename from cryptographie_visuelle.slides.html rename to presentation.html diff --git a/cryptographie_visuelle.ipynb b/presentation.ipynb similarity index 100% rename from cryptographie_visuelle.ipynb rename to presentation.ipynb diff --git a/presentation.slides.html b/presentation.slides.html new file mode 100644 index 0000000..3a90671 --- /dev/null +++ b/presentation.slides.html @@ -0,0 +1,18288 @@ + + + +
+ + + + + + + +# all the imports
+%pylab inline
+
+from visual_cryptography.visual_cryptography import (ImageLayer,
+ produce_image_layer_from_real_image)
+
+
+
+pylab.rcParams['figure.figsize'] = (18.0, 8.0)
++Populating the interactive namespace from numpy and matplotlib + ++
noir = 1
+blanc = 0
+
+def plot_matrix(data, title="", ax=None):
+ if ax is None:
+ fig, ax = pylab.subplots()
+ ax.imshow(data, cmap=plt.cm.gray, interpolation='nearest')
+ if title:
+ ax.set_title(title)
+ ax.axis('off')
+ #pylab.show()
+
+def do_not_show_axis(ax):
+ ax.xaxis.set_major_locator(plt.NullLocator())
+ ax.yaxis.set_major_locator(plt.NullLocator())
+
+def plot_function(f, xmin=-10, xmax=10, ax=None, title=""):
+ if ax is None:
+ fig, ax = pylab.subplots()
+ X = arange(xmin, xmax, 0.1)
+ Y = [f(x) for x in X]
+ ax.plot(X, Y)
+ if title:
+ ax.set_title(title)
+
+def plot_function_in_finite_field(f, xmin=-10, xmax=10, ax=None, title=""):
+ if ax is None:
+ fig, ax = pylab.subplots()
+ X = arange(xmin, xmax, 1)
+ Y = [f(x) for x in X]
+ ax.plot(X, Y, 'r--', alpha=0.75)
+ ax.plot(X, Y, 'bo')
+ if title:
+ ax.set_title(title)
+
+
+def show_sub_pixel(matrix, ax=None, title=""):
+ """Draw Hinton diagram for visualizing a weight matrix."""
+ ax = ax or pylab.gca()
+ if title:
+ ax.set_title(title)
+
+ max_weight = 2**np.ceil(numpy.log(np.abs(matrix).max())/np.log(2))
+
+ ax.patch.set_facecolor('white')
+ ax.set_aspect('equal', 'box')
+ do_not_show_axis(ax)
+
+ for (x,y),w in np.ndenumerate(matrix):
+ if w == 0:
+ color = "white"
+ else:
+ color = "gray"
+ size = 0.8
+ rect = plt.Rectangle([y - size / 2, x - size / 2], size, size,
+ facecolor=color, edgecolor="black")
+ ax.add_patch(rect)
+
+ ax.autoscale_view()
+ ax.invert_yaxis()
+ #pylab.show()
+
+def show_text(text, ax=None):
+ ax = ax or pylab.gca()
+ ax.xaxis.set_major_locator(plt.NullLocator())
+ ax.yaxis.set_major_locator(plt.NullLocator())
+ ax.text(0.5, 0.5,text , color='black',
+ fontsize=40,
+ #fontname='Courier',
+ horizontalalignment='center',
+ verticalalignment='center',
+ )
+ ax.axis('off')
+
+def plot_tuple_of_pixels(pixel_1, pixel_2, axs):
+ show_text("(", axs[0])
+ show_sub_pixel(pixel_1, ax=axs[1])
+ show_text(",", axs[2])
+ show_sub_pixel(pixel_2, ax=axs[3])
+ show_text(")", axs[4])
+Encrypting information in a 100% visual way.
+Sharing a secret between $n$ persons such that any subset of +size $k$ can recover it.
+Using a zero knowledge proof to authenticate ourself to a third +party.
+Let's present the Shamir and Naor ideas to encrypt a message +in a secure way such that the decrypting does not require any computers or calculations.
+The big idea is to encrypt an image on two separate transparents. +When the two transparents are stack togheter, the original image +can be recover.
+img = produce_image_layer_from_real_image("image.png")
+shares = img.produce_two_shares_from_image()
+plot_matrix(shares[0], title='first transparent')
+plot_matrix(shares[1], title='second transparent')
+sum_of_the_shares = shares[0] * shares[1] # note that matplotlib associates 0 to black and 1 to white
+plot_matrix(sum_of_the_shares, title="both transparents")
+The person that creates encrypt the message is called the dealer
+One of the transparent can be called the cypher and the other the key.
+A crytosystem is said to be secure if, without the key, it impossible to +know the original message from the cypher.
+This image is said as the message
+
![]()
We construct each transparent in a pixel by pixel fashion.
+fig, (ax0, ax1, ax2 ) = plt.subplots(ncols=3)
+
+img=matplotlib.image.imread('image.png')
+do_not_show_axis(ax0)
+ax0.imshow(img)
+
+show_sub_pixel([[blanc]*10]*10, ax=ax1, title="transparent 1")
+show_sub_pixel([[blanc]*10]*10, ax=ax2, title="transparent 2")
++-c:43: RuntimeWarning: divide by zero encountered in log + ++
To encrypt a pixel, we'll decompose it in $m$ sub-pixel. Each sub-pixel can be black or white.
+The humain eye will approximate the $m$ sub-pixel in a pixel
+If there is enought black sub-pixel, the eye will see a black pixel
+If there is not enought of black sub-pixel, the eye will see a white pixel
+fig, (ax0, ax1, ax2 ) = plt.subplots(ncols=3)
+
+show_sub_pixel([[noir, noir, noir],
+ [noir, noir, noir],
+ [noir, noir, noir]],
+ ax=ax0,
+ title="a black pixel")
+
+show_sub_pixel([[blanc, noir, noir],
+ [noir, noir, blanc],
+ [blanc, noir, noir]],
+ ax=ax1,
+ title="a black pixel")
+
+show_sub_pixel([[blanc, blanc, noir],
+ [blanc, noir, blanc],
+ [blanc, noir, blanc]],
+ ax=ax2,
+ title="a white pixel")
+To help the humain, we need the black to be as dark as possible and the white to be +as bright as possible
+A pixel is said to be black if it is made of at least $d \leq m$ black sub-pixels
+A pixel is said to be white if it is made of no more than $d - \alpha m$ black sub-pixels
+$m$ is the number of sub-pixels in a pixel
+Bigger $d$ is, darker the blacks are
+Bigger $\alpha$ is, brighter the whites are.
+$\alpha$ represent here a "distance" between the white and black. Greather this distance +will be easier it will be to distinguist between the blacks and whites
+import matplotlib as mpl
+
+fig, ax = pylab.subplots()
+
+cmap = mpl.cm.gray_r
+norm = mpl.colors.Normalize(vmin=5, vmax=10)
+cb = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
+ norm=norm,
+ orientation='horizontal')
+
+ax.set_axis_off()
+ax.text(0.9, 0.5, 'black',
+ horizontalalignment='center',
+ verticalalignment='center',
+ rotation='vertical',
+ size="20",
+ color="white",
+ transform=ax.transAxes)
+
+ax.text(0.1, 0.5, 'white',
+ horizontalalignment='center',
+ verticalalignment='center',
+ rotation='vertical',
+ size="20",
+ color="black",
+ transform=ax.transAxes)
+pylab.show()
+In a way or an other, for each pixel we figured out sub-pixel to place on each transparent +such that.
+when stacked, they form the the original image
+with only one transparent, it is impossible to know what is the original image
+fig, (ax0, ax1, ax2 ) = plt.subplots(ncols=3)
+
+plot_matrix(shares[0], title='first transparent', ax=ax0)
+plot_matrix(shares[1], title='second transparent', ax=ax1)
+plot_matrix(shares[1] * shares[0], title='stacked transparents', ax=ax2)
+We encode a pixel in an array of size $m$, $[ p_1, p_2, \dots, p_m ]$
+where $i$ represents a specific sub-pixel position
+the $i^th$ sub-pixel is black is $p_i$ is $1$ and white if $p_i$ is $0$
+show_sub_pixel([[noir, blanc, noir],
+ [blanc, noir, blanc],
+ [blanc, blanc, blanc]], title="[1 0 1 0 1 0 0 0 0]")
+Consequently the transparent superposition can be seen as componentwise or operation
+ [1 0 1 0 ]
++ [1 1 0 0 ]
+-----------------------
+ [1 1 1 0 ]
+
+fig, (ax0, ax1, ax2, ax3, ax4 ) = plt.subplots(ncols=5)
+show_sub_pixel([[noir, blanc],
+ [noir, blanc]], title="[1 0 1 0]", ax=ax0)
+
+show_text("+", ax1)
+
+show_sub_pixel([[noir, noir],
+ [blanc, blanc]], title="[1 1 0 0]", ax=ax2)
+
+show_text("=", ax3)
+
+show_sub_pixel([[noir, noir],
+ [noir, blanc]], title="[1 1 1 0]", ax=ax4)
+How can we encode a pixel $P$ (black or white) in two pixels $Q_1$ $Q_2$ such that...
+$Q_1 + Q_2 \sim P$
+Without having access to $Q_1$ and $Q_2$, we grain no knowledge on $P$
+$$ + Prob(\text{P is white} | Q_i) = Prob(\text{P is black} | Q_i) +$$
+
+$A \sim B$ if $A$ is the same colour as $B$
+We create two sets
+$W = \{ (r_1, l_1) , (r_2, l_2), \dots, (r_k, l_k) \}$
+$K = \{ (g_1, d_1) , (g_2, d_2), \dots, (g_k, d_k) \}$
+such that...
+$r_i + l_i$ is white
+$g_i + d_i$ is black
+The cardinality of $x$ in the multiset $\{r_1, l_1, \dots r_k, l_k\}$ is +the same in the multiset $\{g_1, d_1, \dots g_k, d_k\}$.
+fig, axs = plt.subplots(ncols=14)
+
+pixel = lambda a, b, c, d : [[a, b], [c, d]]
+w, b = blanc, noir
+
+show_text("white={ ", axs[0])
+show_text(" ", axs[1])
+plot_tuple_of_pixels(pixel(w, b, w, b), pixel(w, b, w, b), axs[2:])
+show_text(",", axs[7])
+plot_tuple_of_pixels(pixel(b, w, b, w), pixel(b, w, b, w), axs[8:])
+show_text("}", axs[13])
+fig, axs = plt.subplots(ncols=14)
+
+pixel = lambda a, b, c, d : [[a, b], [c, d]]
+w, b = blanc, noir
+
+show_text("black={ ", axs[0])
+show_text(" ", axs[1])
+plot_tuple_of_pixels(pixel(w, b, w, b), pixel(b, w, b, w), axs[2:])
+show_text(",", axs[7])
+plot_tuple_of_pixels(pixel(b, w, b, w), pixel(w, b, w, b), axs[8:])
+show_text("}", axs[13])
+fig, axs = plt.subplots(ncols=14)
+
+pixel = lambda a, b, c, d : [[a, b], [c, d]]
+w, b = blanc, noir
+
+show_text("white={ ", axs[0])
+show_text(" ", axs[1])
+plot_tuple_of_pixels(pixel(w, b, b, w), pixel(w, b, b, w), axs[2:])
+show_text(",", axs[7])
+plot_tuple_of_pixels(pixel(b, w, w, b), pixel(b, w, w, b), axs[8:])
+show_text("}", axs[13])
+fig, axs = plt.subplots(ncols=14)
+
+pixel = lambda a, b, c, d : [[a, b], [c, d]]
+w, b = blanc, noir
+
+show_text("black={ ", axs[0])
+show_text(" ", axs[1])
+plot_tuple_of_pixels(pixel(w, b, b, w), pixel(b, w, w, b), axs[2:])
+show_text(",", axs[7])
+plot_tuple_of_pixels(pixel(b, w, w, b), pixel(w, b, b, w), axs[8:])
+show_text("}", axs[13])
+fig, axs = plt.subplots(ncols=14)
+
+pixel = lambda a, b : [[a, b]]
+w, b = blanc, noir
+
+show_text("white={ ", axs[0])
+show_text(" ", axs[1])
+plot_tuple_of_pixels(pixel(w, b), pixel(w, b), axs[2:])
+show_text(",", axs[7])
+plot_tuple_of_pixels(pixel(b, w), pixel(b, w), axs[8:])
+show_text("}", axs[13])
+fig, axs = plt.subplots(ncols=14)
+
+pixel = lambda a, b : [[a, b]]
+w, b = blanc, noir
+
+show_text("black={ ", axs[0])
+show_text(" ", axs[1])
+plot_tuple_of_pixels(pixel(w, b), pixel(b, w), axs[2:])
+show_text(",", axs[7])
+plot_tuple_of_pixels(pixel(b, w), pixel(w, b), axs[8:])
+show_text("}", axs[13])
+By crafting its own transparent, knowing the other transparent, +a cheater could show whatever he wants as a results
+cheated = produce_image_layer_from_real_image("cheatedimage.png")
+cheated_share = cheated.produce_cheated_image_from_other_share(shares[0])
+
+plot_matrix(cheated_share , title='crafted transparent')
+
+savefig("crafted_transparen.pdf")
+plot_matrix(cheated_share * shares[0], title='forge results')
+Alice wants to share his swiss bank account number with Bob TheFirst, Bob TheSecond, Bob TheThird,... Bob TheNth such that...
+If any $k$ Bobs comes togheter they need to be able to recover the bank account number
+If any less that $k$ Bobs comes togheter they need to have no idea whatsoever about the bank account number
+ ***********
+ ***** ***********
+ ** ****** *** ********
+ **** ****** ** *******
+ *** ******* ** ******
+ *** ** * **
+ *|/------ -------\ ** *
+ | |=| :===**
+ | O | | O | }|*
+ |---- | ---- | |*
+ | |___ |\/
+ | |
+ \ ----- |
+ \ |
+ -__ -- -/
+
+A polynomial is a function that can be written as
+$$ + a_0 + a_1 \cdot x^1 + a_2 \cdot x^2 + \dots + a_n \cdot x^n +$$
+fig, (ax0, ax1, ax2) = plt.subplots(ncols=3)
+plot_function(lambda x : 2 * x + 1, title="$2 \cdot x + 1$", ax=ax0)
+plot_function(lambda x : 2 * x**2 + 1, title="$2 \cdot x^2 + 1$", ax=ax1)
+plot_function(lambda x : 2 * x**3 - 2 * x**2 + 1, title="$2 \cdot x^3 - 2 \cdot x^2 + 1$", ax=ax2)
+Any $n + 1$ points define an unique polynomials of degre $n$.
+fig, (ax0, ax1, ax2) = plt.subplots(ncols=3)
+
+p = lambda x : 2 * x + 1
+plot_function(p, title="$2 \cdot x + 1$", ax=ax0)
+ax0.plot([-7, 7] , [p(-7), p(7)], "ro")
+
+p = lambda x : 2 * x**2 + 1
+plot_function(p, title="$2 \cdot x^2 + 1$", ax=ax1)
+ax1.plot([-7, 0, 7], [p(-7), p(0), p(7)], "ro")
+
+
+
+p = lambda x : 2 * x**3 - 2 * x**2 + 1
+plot_function(p, title="$2 \cdot x^3 - 2 \cdot x^2 + 1$", ax=ax2)
+ax2.plot([-7, -3, 3, 7], [p(-7), p(-3), p(3), p(7)], "ro")
+show()
+by $n$ points pass an infinite number of polynomials of degree $n$
+fig, ax = plt.subplots()
+
+b = 0
+d = 1
+c = lambda a : -100 - 7**2 * a
+
+P = lambda a : (lambda x: a * x**3 + b * x**2 + x * c(a) + d)
+
+for i in range(-12, 12, 3):
+ plot_function(P(i), ax=ax)
+
+
+p = P(1)
+ax.plot([-7, 0, 7] , [p(-7), p(0), p(7)], "ro")
+ax.set_title("Polynomials passing through $(-7, 701), (0, 1), (7, -699)$")
+fig.show()
+$$ P(x) = a_0 + a_1 \cdot x^1 + a_2 \cdot x^2 + \dots + a_{k-1}\cdot x^{x-1} $$
+If $K$ bob comes togheter, they can figure out the secret polynomial $P(x)$ and compute $P(0)$
+Peter wants to share between Wolf and Didier the
+ACS's credit card: 5243 9021 9129 1828.
p = lambda x : 5243902191291828 + 7873787349 * x + 7893478934 * x ** 2
+credit_card_number = 5243902191291828
+wolf_secret = p(1) # keyboard random number
+didier_secret = p(2)
+print(wolf_secret)
+print(didier_secret)
++5243917958558111 +5243949512782262 + ++
Peter choose the bellow polynomials because he likes it very much
+$$P(X) = 5243902191291828 + 7873787349\cdot x + 7893478934\cdot x^2$$
+Didier will try to figure out the credit card number to buy a +truck load of maple sirup.
+He knows that he is looking for a number $a_0$ of 12 digits
+$a_0$ is positive
+$a_0$ is an integer
+... +$$P(x) = a_0 + a_1 \cdot x + a_2 \cdot x^2 $$ +$$5243949512782262 = a_0 + a_1 \cdot 2 + a_2 \cdot 4 $$ +$$a_0 = 5243949512782262 - a_1 \cdot 2 - a_2 \cdot 4$$ +$$a_0 = 5243949512782262 - 2\cdot(a_1 \cdot - 2 \cdot a_2)$$ +$$a_0 = 5243949512782262 - \text{even number}$$
+Didier knows the credit card number is even
+With the help of EC2 Didier can find the solution in a relative small amount of time.
+We could process the original message before wharing it
+$$\underbrace{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}_\text{very random number}\underbrace{5243902191291828}_\text{the credit card number}$$
+We could work in a more appropriate field
+$$\mathbb{Z}/p\mathbb{Z}$$
+| x | +0 | +1 | +2 | +3 | +4 | +5 | +6 | +
|---|---|---|---|---|---|---|---|
| 0 | +0 | +0 | +0 | +0 | +0 | +0 | +0 | +
| 1 | +0 | +1 | +2 | +3 | +4 | +5 | +6 | +
| 2 | +0 | +2 | +4 | +6 | +1 | +3 | +5 | +
| 3 | +0 | +3 | +6 | +2 | +5 | +1 | +4 | +
| 4 | +0 | +4 | +1 | +5 | +2 | +6 | +3 | +
| 5 | +0 | +5 | +3 | +1 | +6 | +4 | +2 | +
| 6 | +0 | +6 | +5 | +4 | +3 | +2 | +1 | +
| + | +0 | +1 | +2 | +3 | +4 | +5 | +6 | +
|---|---|---|---|---|---|---|---|
| 0 | +0 | +1 | +2 | +3 | +4 | +5 | +6 | +
| 1 | +1 | +2 | +3 | +4 | +5 | +6 | +0 | +
| 2 | +2 | +3 | +4 | +5 | +6 | +0 | +1 | +
| 3 | +3 | +4 | +5 | +6 | +0 | +1 | +2 | +
| 4 | +4 | +5 | +6 | +0 | +1 | +2 | +3 | +
| 5 | +5 | +6 | +0 | +1 | +2 | +3 | +4 | +
| 6 | +6 | +0 | +1 | +2 | +3 | +4 | +5 | +
fig, (ax0, ax1, ax2) = plt.subplots(ncols=3)
+plot_function_in_finite_field(lambda x : (2 * x + 1) % 7, title="$2 \cdot x + 1$ mod 7", ax=ax0)
+plot_function_in_finite_field(lambda x : (2 * x**2 + 1) % 7, title="$2 \cdot x^2 + 1$ mod 7", ax=ax1)
+plot_function_in_finite_field(lambda x : (2 * x**3 - 2 * x**2 + 1) % 7, title="$2 \cdot x^3 - 2 \cdot x^2 + 1$ mod 7", ax=ax2)
+fig, ax = plt.subplots()
+f = lambda x : (2 * x**3 - 2 * x**2 + 1) % 7
+plot_function_in_finite_field(f, title="$2 \cdot x^3 - 2 \cdot x^2 + 1 mod 7$", ax=ax)
+ax.plot([-7, 0, 7], [f(-7), f(0), f(7)], 'rD')
+fig.show()
+fig, ax = plt.subplots()
+
+b = 0
+d = 1
+c = lambda a : -100 - 7**2 * a
+
+P = lambda a : (lambda x: (a * x**3 + b * x**2 + x * c(a) + d) % 7)
+
+for i in range(-12, 12, 3):
+ plot_function_in_finite_field(P(i), ax=ax)
+
+
+p = P(1)
+ax.plot([-7, 0, 7] , [p(-7), p(0), p(7)], "ro")
+ax.set_title("Polynomials passing through $(-7, 1), (0, 1), (7, 1)$")
+fig.show()
+If peter would have choosen polynomials in $\mathbb{Z}/p\mathbb{Z}$ with $p$ big enough...
+Didier could not have easely discarted some numbers
+For Didier, a large $p$ in infinite even with the help of $aws$
+The objective of this sections is to present the idea of the +article how to proof yourself, +an article publish by Fiat and Shamir in the year of grace 1987.
+The objective is to find a way to allow Alice to authenticate to Bob such that...
+Alice can authenticate
+Bob is sure that the Alice is really Alice
+Bob cannot copy the credentials of alice in any way.
+Completness
+Soundness
+Zero-knowledge
+Bob and Alice exchange some information while they know they are talking to the each other (sign up)
+In that exchange, Alice will tell Bob that she knows something, proof without giving Bob or anyone else +any factual proof.
+Each time Alice will authenticate, Alice will provide enough information to Bob to demonstrate that she knows the +information but without giving any factual proofs.
+There are some problems that are easy to solve in $\mathbb{R}$ but very hard to solve in $\mathbb{Z}/n\mathbb{Z}$
+The quandratric residue of $x$ in $\mathbb{Z}/n\mathbb{Z}$ is an +element $y$ such that $x^2 = y$
+We say that $y$ is a quadratic residue if there exists $x$ such +that $x^2 = y$
+not every elements are quadratic residue
+It is hard to know if a number is a quadratic residue
+It is easy to find a quadratic residue: just take a random +$r$ and compute $r^2$
+The idea is that Alice will demonstrate to Bob that she knows that a certain element $x$ is a quadratic residue +without giving $\omega$ such that $\omega ^2 = x$
+| Alice | +Bob | +
|---|---|
| chose a random $r$ | ++ |
| sends $a = r^2$ | ++ |
| + | send challenge 0 or 1 at random | +
| if challenge is 1 returns r | +accept if $r^2 = a$ | +
| if challenge is 0 returns $r\cdot\omega$ | +accept is $(r\cdot\omega)^2 = a \cdot x$ | +
completeness: + If Alice plays the game, she will be to proof that she is herself with probability 1
+soundness: + Bob as a probablylity $1/2$ to catch a cheeter
+zero-knowledge: + Proof by intimidation
+
+