2023-05-29 16:13:54 +00:00
|
|
|
from consts import *
|
|
|
|
from components import *
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
from manim import *
|
|
|
|
|
|
|
|
|
|
|
|
class Introduction(TitledScene):
|
|
|
|
def construct(self):
|
|
|
|
self.add_title("Goldreich--Goldwasser--Halevi")
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
text_1 = Tex(
|
|
|
|
r"""
|
|
|
|
\begin{itemize}
|
|
|
|
\item Lattice-based cryptosystem.
|
|
|
|
\item Devised in 1997 by Goldreich, Goldwasser, and Halevi.
|
|
|
|
\item Broken in 1999 by Nguyen.
|
|
|
|
\end{itemize}
|
|
|
|
""",
|
|
|
|
font_size=MEDIUM_FONT,
|
|
|
|
)
|
|
|
|
self.add(text_1)
|
|
|
|
self.play(Write(text_1, run_time=4.0))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
|
|
|
|
class Premise(TitledScene):
|
|
|
|
def construct(self):
|
|
|
|
self.add_title("Lattices")
|
|
|
|
|
|
|
|
# A lattice is a subspace of a vector space that is constructed by taking integer multiples of some basis
|
|
|
|
# vectors.
|
|
|
|
# For example, take the real plane R2.
|
|
|
|
plane = NumberPlane(axis_config={"stroke_width": 0.0})
|
|
|
|
plane.set_z_index(-10)
|
|
|
|
plane.set_opacity(0.75)
|
|
|
|
dot = Dot(ORIGIN)
|
|
|
|
self.add(dot, plane)
|
|
|
|
self.play(Create(dot), Create(plane))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
# We can construct the 2D grid of integers with the elementary basis
|
|
|
|
lattice_1 = VGroup()
|
|
|
|
arrow_1 = Arrow(ORIGIN, [1, 0, 0], buff=0)
|
|
|
|
arrow_2 = Arrow(ORIGIN, [0, 1, 0], buff=0)
|
|
|
|
|
|
|
|
self.play(Create(arrow_1), Create(arrow_2))
|
|
|
|
self.wait()
|
|
|
|
|
2023-05-30 13:01:55 +00:00
|
|
|
for i in range(-50, 50):
|
|
|
|
for j in range(-25, 25):
|
2023-05-29 16:13:54 +00:00
|
|
|
lattice_1.add(Dot([i, j, 0]))
|
|
|
|
|
|
|
|
self.play(Create(lattice_1))
|
|
|
|
|
|
|
|
# By moving these basis vectors but maintaining their linear independency, other lattices can be formed
|
|
|
|
self.play(
|
|
|
|
Transform(arrow_1, Arrow(ORIGIN, [1.5, 0, 0], buff=0)),
|
|
|
|
*[
|
|
|
|
Transform(
|
|
|
|
dot,
|
|
|
|
Dot(
|
|
|
|
dot.get_center()
|
|
|
|
* np.matrix([[1.5, 0, 0], [0, 1, 0], [0, 0, 1]])
|
|
|
|
),
|
|
|
|
)
|
|
|
|
for dot in lattice_1
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
Transform(arrow_1, Arrow(ORIGIN, [1, -0.5, 0], buff=0)),
|
|
|
|
*[
|
|
|
|
Transform(
|
|
|
|
dot,
|
|
|
|
Dot(
|
|
|
|
dot.get_center()
|
|
|
|
* np.matrix([[2 / 3, 0, 0], [0, 1, 0], [0, 0, 1]])
|
|
|
|
* np.matrix([[1, -0.5, 0], [0, 1, 0], [0, 0, 1]])
|
|
|
|
),
|
|
|
|
)
|
|
|
|
for dot in lattice_1
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
Transform(arrow_1, Arrow(ORIGIN, [1, -1, 0], buff=0)),
|
|
|
|
Transform(arrow_2, Arrow(ORIGIN, [1, 1, 0], buff=0)),
|
|
|
|
*[
|
|
|
|
Transform(
|
|
|
|
dot,
|
|
|
|
Dot(
|
|
|
|
dot.get_center()
|
|
|
|
* np.matrix([[1, 0.5, 0], [0, 1, 0], [0, 0, 1]])
|
|
|
|
* np.matrix([[1, -1, 0], [1, 1, 0], [0, 0, 1]])
|
|
|
|
),
|
|
|
|
)
|
|
|
|
for dot in lattice_1
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.wait()
|
2023-05-30 13:01:55 +00:00
|
|
|
|
|
|
|
self.play(
|
|
|
|
Transform(arrow_1, Arrow(ORIGIN, [2, 0, 0], buff=0)),
|
|
|
|
*[
|
|
|
|
Transform(
|
|
|
|
dot,
|
|
|
|
Dot(
|
|
|
|
dot.get_center()
|
|
|
|
* np.matrix([[1 / 2, 1 / 2, 0], [-1 / 2, 1 / 2, 0], [0, 0, 1]])
|
|
|
|
* np.matrix([[2, 0, 0], [1, 1, 0], [0, 0, 1]])
|
|
|
|
),
|
|
|
|
)
|
|
|
|
for dot in lattice_1
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
|
|
|
|
class MatrixRep(TitledScene):
|
|
|
|
def construct(self):
|
|
|
|
self.add_title("Lattices")
|
|
|
|
|
|
|
|
matrix_comp = MathTex(
|
|
|
|
r"\begin{bmatrix}1 & 1\\ 1 & -1\end{bmatrix} \sim \begin{bmatrix}1 & 2\\ 1 & 0\end{bmatrix}"
|
|
|
|
)
|
|
|
|
lattice_comp = MathTex(
|
|
|
|
r"L\left(\begin{bmatrix}1 & 1\\ 1 & -1\end{bmatrix}\right) = L\left(\begin{bmatrix}1 & 2\\ 1 & 0\end{bmatrix}\right)"
|
|
|
|
)
|
|
|
|
|
|
|
|
self.play(Create(matrix_comp))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(Transform(matrix_comp, lattice_comp))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(ApplyMethod(matrix_comp.shift, 2 * UP))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
l_def = MathTex(
|
|
|
|
r"L(\begin{bmatrix}\mathbf{b_1} & \mathbf{b_2}\end{bmatrix}) = \{ k_1 \mathbf{b_1} + k_2 \mathbf{b_2} \mid k_i \in \mathbb{Z} \}"
|
|
|
|
)
|
|
|
|
|
|
|
|
l_def.shift(DOWN)
|
|
|
|
|
|
|
|
self.play(Create(l_def))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
|
2023-05-30 14:03:21 +00:00
|
|
|
class LatticeProblems(Scene):
|
|
|
|
def construct(self):
|
|
|
|
text = Tex("How does this give us a trapdoor?", font_size=LARGE_FONT)
|
|
|
|
|
|
|
|
self.play(Create(text))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(Transform(text, Tex("Lattice problems", font_size=LARGE_FONT)))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(ApplyMethod(text.to_corner, UP + LEFT))
|
|
|
|
self.wait()
|
|
|
|
|
2023-06-03 16:28:17 +00:00
|
|
|
diagram_1 = VGroup()
|
|
|
|
diagram_1.add(Dot(ORIGIN))
|
|
|
|
diagram_1.add(Arrow(ORIGIN, [0.25, 1, 0], buff=0))
|
|
|
|
diagram_1.add(Arrow(ORIGIN, [0.5, 1, 0], buff=0))
|
|
|
|
arrow = Arrow(ORIGIN, [1, 0, 0], buff=0)
|
|
|
|
arrow.set_color(BLUE)
|
|
|
|
arrow.set_z_index(-1)
|
|
|
|
diagram_1.add(arrow)
|
|
|
|
|
|
|
|
diagram_1.shift(3 * LEFT)
|
|
|
|
label_1 = Tex("Closest Vector Problem", font_size=MEDIUM_FONT)
|
|
|
|
label_1.next_to(diagram_1, DOWN)
|
|
|
|
|
|
|
|
diagram_2 = VGroup()
|
|
|
|
diagram_2.add(Dot(ORIGIN))
|
|
|
|
diagram_2.add(Arrow(ORIGIN, [1, 1, 0], buff=0))
|
|
|
|
diagram_2.add(Arrow(ORIGIN, [-1, 0, 0], buff=0))
|
|
|
|
arrow_1 = Arrow(ORIGIN, [1, 0, 0], buff=0)
|
|
|
|
arrow_1.set_color(BLUE)
|
|
|
|
arrow_1.set_z_index(-1)
|
|
|
|
diagram_2.add(arrow_1)
|
|
|
|
arrow_2 = Arrow(ORIGIN, [0, 1, 0], buff=0)
|
|
|
|
arrow_2.set_color(BLUE)
|
|
|
|
arrow_2.set_z_index(-1)
|
|
|
|
diagram_2.add(arrow_2)
|
|
|
|
|
|
|
|
diagram_2.shift(3 * RIGHT)
|
|
|
|
label_2 = Tex("Shortest Basis Problem", font_size=MEDIUM_FONT)
|
|
|
|
label_2.next_to(diagram_2, DOWN)
|
|
|
|
|
|
|
|
self.play(Create(diagram_1), Create(diagram_2))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(Create(label_1), Create(label_2))
|
|
|
|
self.wait()
|
|
|
|
|
2023-05-30 14:03:21 +00:00
|
|
|
|
|
|
|
class OrthoDefect(Scene):
|
2023-05-30 13:01:55 +00:00
|
|
|
def construct(self):
|
|
|
|
text = Tex("How do we decide which bases are ``good''?", font_size=LARGE_FONT)
|
|
|
|
|
|
|
|
self.play(Create(text))
|
|
|
|
self.wait()
|
|
|
|
|
2023-05-30 14:03:21 +00:00
|
|
|
self.play(Transform(text, Tex("Orthogonal defect", font_size=LARGE_FONT)))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(ApplyMethod(text.to_corner, UP + LEFT))
|
2023-05-30 13:01:55 +00:00
|
|
|
self.wait()
|
|
|
|
|
|
|
|
diagram_1 = VGroup()
|
|
|
|
diagram_1.add(Dot(ORIGIN))
|
|
|
|
diagram_1.add(Arrow(ORIGIN, [1, 0, 0], buff=0))
|
|
|
|
diagram_1.add(Arrow(ORIGIN, [0, 1, 0], buff=0))
|
|
|
|
|
2023-06-03 16:28:17 +00:00
|
|
|
diagram_1.shift(3 * LEFT)
|
2023-05-30 13:01:55 +00:00
|
|
|
diagram_1.set_color(GREEN)
|
2023-05-30 14:03:21 +00:00
|
|
|
label_1 = Tex("Defect 1", font_size=MEDIUM_FONT)
|
2023-05-30 13:01:55 +00:00
|
|
|
label_1.next_to(diagram_1, DOWN)
|
|
|
|
|
|
|
|
diagram_2 = VGroup()
|
|
|
|
diagram_2.add(Dot(ORIGIN))
|
|
|
|
diagram_2.add(Arrow(ORIGIN, [0.25, 1, 0], buff=0))
|
|
|
|
diagram_2.add(Arrow(ORIGIN, [0.5, 1, 0], buff=0))
|
|
|
|
|
2023-06-03 16:28:17 +00:00
|
|
|
diagram_2.shift(3 * RIGHT)
|
2023-05-30 13:01:55 +00:00
|
|
|
diagram_2.set_color(RED)
|
|
|
|
label_2 = Tex(r"Defect $\approx$ 4.6", font_size=MEDIUM_FONT)
|
|
|
|
label_2.next_to(diagram_2, DOWN)
|
|
|
|
|
|
|
|
self.play(Create(diagram_1), Create(diagram_2))
|
|
|
|
self.wait()
|
|
|
|
|
|
|
|
self.play(Create(label_1), Create(label_2))
|
|
|
|
self.wait()
|