Skip to content

Instantly share code, notes, and snippets.

@nathanielbd
Created March 21, 2023 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathanielbd/f45970af570c74dc9676a3fd4b9b728c to your computer and use it in GitHub Desktop.
Save nathanielbd/f45970af570c74dc9676a3fd4b9b728c to your computer and use it in GitHub Desktop.
Manim animation of the double-and-add algorithm for elliptic curve point multiplication
#!/usr/bin/env python
from manim import *
# usage: python3 -m manim double_add.py DoubleAdd -p
class DoubleAdd(Scene):
def construct(self):
n_bin = Text("n = 101010")
self.play(Write(n_bin))
self.wait(1)
Q = MathTex(r"Q = P", substrings_to_isolate="Q") \
.next_to(n_bin, 7*LEFT+3*DOWN) \
.set_color_by_tex("Q", ORANGE)
R = MathTex(r"R = \mathcal{O}", substrings_to_isolate="R") \
.next_to(Q, 3*DOWN) \
.set_color_by_tex("R", PINK)
self.play(
Write(Q),
Write(R)
)
up_arrow = Arrow(
n_bin[-1].get_center()+1.5*DOWN,
n_bin[-1].get_center()+0.25*DOWN
)
odd = Text("1?").next_to(up_arrow, DOWN).set_color(YELLOW)
yes = Text("✓").next_to(up_arrow, DOWN).set_color(GREEN)
no = Text("✗").next_to(up_arrow, DOWN).set_color(RED)
arrow_and_checker = Group(up_arrow, odd)
self.play(
FadeIn(arrow_and_checker)
)
q = 1
r = 0
for idx in range(1, 7):
self.wait(1)
self.play(Wiggle(odd))
if idx % 2 == 1:
self.play(Transform(odd, no))
self.wait(1)
else:
self.play(Transform(odd, yes))
self.wait(1)
R_text = r'\mathcal{O}' if r == 0 else f'{q}P'
new_R = MathTex(f"R = {R_text} + Q", substrings_to_isolate=["R", "Q"]) \
.next_to(R, ORIGIN).set_color_by_tex("R", PINK).set_color_by_tex("Q", ORANGE)
self.play(
Transform(R, new_R)
)
self.wait(1)
r += q
self.play(Transform(R,
MathTex(f"R = {r}P", substrings_to_isolate=["R", "Q"]) \
.next_to(R, ORIGIN).set_color_by_tex("R", PINK).set_color_by_tex("Q", ORANGE)
))
self.wait(1)
self.play(
n_bin[:-idx].animate.shift(n_bin[-idx].get_center()-n_bin[-idx-1].get_center()),
n_bin[-idx].animate.set_color(BLACK).shift(IN)
)
self.wait(1)
self.play(Transform(Q,
MathTex(fr"Q = {'' if q == 1 else q}P \cdot 2", substrings_to_isolate="Q")
.next_to(Q, ORIGIN).set_color_by_tex("Q", ORANGE)
))
q *= 2
self.wait(1)
self.play(Transform(Q,
MathTex(fr"Q = {q}P", substrings_to_isolate="Q")
.next_to(Q, ORIGIN).set_color_by_tex("Q", ORANGE)
))
self.wait(1)
self.play(Transform(odd, Text("1?").next_to(up_arrow, DOWN).set_color(YELLOW)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment