diff options
Diffstat (limited to 'src')
27 files changed, 909 insertions, 0 deletions
diff --git a/src/blog/2025-02-27-elliptic-curves-javascript/ecm.md b/src/blog/2025-02-27-elliptic-curves-javascript/ecm.md new file mode 100644 index 0000000..56b876c --- /dev/null +++ b/src/blog/2025-02-27-elliptic-curves-javascript/ecm.md | |||
| @@ -0,0 +1,283 @@ | |||
| 1 | # Elliptic curves and JavaScript | ||
| 2 | |||
| 3 | At my company we regularly have talks and other knowledge events. | ||
| 4 | After attending many of these events, I decided to give a talk | ||
| 5 | about [elliptic curves](https://en.wikipedia.org/wiki/Elliptic_curve), | ||
| 6 | which I worked with during my PhD. | ||
| 7 | |||
| 8 | The intended audience consists of software developers, but their | ||
| 9 | background is mixed: some have studied Maths in university, but many did | ||
| 10 | not. Most are not familiar with abstract algebra other than polynomials | ||
| 11 | and matrices, let alone algebraic geometry. Considering all of this, | ||
| 12 | I decided to give a presentation about | ||
| 13 | [Lenstra elliptic curve factorization](https://en.wikipedia.org/wiki/Lenstra_elliptic-curve_factorization), | ||
| 14 | so I could also show some code and do a practical demo. | ||
| 15 | |||
| 16 | Since I gave a presentation on this topic to a different audience a | ||
| 17 | couple of years ago, I could have simply adapted the slides and used the | ||
| 18 | same code. Instead, I took this as an opportunity to experiment with | ||
| 19 | new tools and languages. This post is a summary of what I have learned | ||
| 20 | while preparing this talk. | ||
| 21 | |||
| 22 | All the code I talk about in this post, including the source for the | ||
| 23 | slides, can be found in [this git repository](https://git.tronto.net/ecm). | ||
| 24 | |||
| 25 | ## The code | ||
| 26 | |||
| 27 | For the practical part of the talk I had to write some code to demonstrate | ||
| 28 | the factorization algorithm. It's not much, maybe 200 lines or so, and | ||
| 29 | I already had a working Python version. It was a rather straightforward | ||
| 30 | implementation, and it used exceptions to handle the "a factor was found" | ||
| 31 | part of the algorithm; although this is not amazing coding style, it | ||
| 32 | was faithful to how the algorithm was originally explained - or to how | ||
| 33 | I wanted to explain it, anyway. | ||
| 34 | |||
| 35 | It was not bad code, but I wanted to experiment with something new. | ||
| 36 | |||
| 37 | ### Adventures in C++ | ||
| 38 | |||
| 39 | Recently I have been learning C++, and I wanted to experiment with some | ||
| 40 | of its more advanced features. So I decided to rewrite the whole thing. | ||
| 41 | |||
| 42 | I had a clear idea of where I wanted to start: a small | ||
| 43 | [library for modular arithmetic](https://git.tronto.net/zmodn/file/README.md.html), | ||
| 44 | with compile-time fixed | ||
| 45 | [modulus](https://en.wikipedia.org/wiki/Modular_arithmetic) via templates | ||
| 46 | and heavy use of | ||
| 47 | [type inference](https://en.wikipedia.org/wiki/Type_inference) | ||
| 48 | for seamless operations between regular integers and integers modulo N. | ||
| 49 | This endeavor was quite successful, and it taught me how to use | ||
| 50 | templates and concepts, which I have talked about in | ||
| 51 | [my previous blog post](../2025-01-21-taming-cpp-templates). | ||
| 52 | |||
| 53 | When working on the previous part, I made sure that any kind of integer | ||
| 54 | could be used as a base type for the modular integers, so I could use | ||
| 55 | some custom big integer types to show off the power of the factorization | ||
| 56 | algorithm with very large numbers. Unfortunately, I did not take into | ||
| 57 | account that with my setup I needed a big integer class that supported | ||
| 58 | *compile-time constants* - for example in the form of `constexpr` | ||
| 59 | constructors. I could not find any, so I decided to write | ||
| 60 | [my own big integer class](https://git.tronto.net/zmodn/file/bigint.h.html). | ||
| 61 | This was less successful: implementing an *efficient* big integer library | ||
| 62 | was not as straightforward as the modular integers library. I decided | ||
| 63 | not to care about efficiency for the time being, but that would come | ||
| 64 | back to bite me very soon. | ||
| 65 | |||
| 66 | Finally, I put these two libraries together and implemented the elliptic | ||
| 67 | curve factorization algorithm. This was not hard. The only problem was | ||
| 68 | that it was excruciatingly slow when I used large numbers, undoubtedly | ||
| 69 | due to my half-assed big integer implementation. I could restrict | ||
| 70 | myself to using regular 64-bit integers, but then I would have to use | ||
| 71 | to relatively small numbers, making the demo less interesting. I looked | ||
| 72 | online for other big integer libraries that I could use and I found | ||
| 73 | [ctbignum](https://github.com/niekbouman/ctbignum), but I could not make | ||
| 74 | it work together with my modular arithmetic class. The day of the | ||
| 75 | presentation was approaching quickly, so I decided to go back to | ||
| 76 | my original Python implementation instead. | ||
| 77 | |||
| 78 | ### Back to Python | ||
| 79 | |||
| 80 | When I looked back at my old Python implementation, I found it nicer | ||
| 81 | and cleaner than how I remembered it. I did not have to do much | ||
| 82 | cleanup, it was pretty much ready to go, and much more readable than | ||
| 83 | the C++ verion for anyone who is not a C++ expert - and probably for C++ | ||
| 84 | experts too. Moreover, Python's seamless use of large integers was | ||
| 85 | exactly what I was missing from the C++ version. | ||
| 86 | |||
| 87 | One of the few changes I made to this code was reworking a little bit | ||
| 88 | the "elliptic curve point" class I used. If anything, this was a good | ||
| 89 | excuse to learn about | ||
| 90 | [dataclasses](https://docs.python.org/3/library/dataclasses.html). I also | ||
| 91 | decided to add | ||
| 92 | [type hints](https://docs.python.org/3/library/typing.html), which I | ||
| 93 | have recently found out about. | ||
| 94 | |||
| 95 | And with little work, the old code was ready to go! | ||
| 96 | |||
| 97 | ## The slides | ||
| 98 | |||
| 99 | Compared to the code, the slides needed a few more adjustments. | ||
| 100 | When I gave this talk the first time, it was for an audience of | ||
| 101 | Math students at the end of their Bachelor program. I could freely | ||
| 102 | use all that Math jargon that we Mathematicians like, such as | ||
| 103 | "let K be a | ||
| 104 | [field](https://en.wikipedia.org/wiki/Field_(mathematics))" | ||
| 105 | and "E is a | ||
| 106 | [projective](https://en.wikipedia.org/wiki/Projective_space) curve". | ||
| 107 | But this time I had to phrase things differently. The content itself | ||
| 108 | didn't need much change, but I had to use a more approachable language, | ||
| 109 | at the cost of being a little less rigorous. For example, I could | ||
| 110 | get rid of all the projective plane business by just saying "let's | ||
| 111 | pretend that there is a point *at infinity*; trust me, the Math | ||
| 112 | works out". | ||
| 113 | |||
| 114 | The problem with changing the old slides is that I did not want to touch | ||
| 115 | [LaTeX](https://nl.wikipedia.org/wiki/LaTeX) | ||
| 116 | anymore. As a Mathematician I like it because it can do pretty much everything | ||
| 117 | you need (did you know you can | ||
| 118 | [draw diagrams programmatically](https://www.youtube.com/watch?v=mWqhB6qOIk0)?), | ||
| 119 | but as a computer scientist I'd rather not deal with the mess that is a | ||
| 120 | LaTeX installation. | ||
| 121 | So what did I decide to use instead? HTML, CSS and a bit of JavaScript! | ||
| 122 | |||
| 123 | ### Math formulas with MathJax | ||
| 124 | |||
| 125 | Even without LaTeX, I still needed a way to write Math formulas in my | ||
| 126 | slides. One way to achieve this is using [MathJax](https://www.mathjax.org), | ||
| 127 | which allows you to write LaTeX or | ||
| 128 | [MathML](https://en.wikipedia.org/wiki/MathML) formulas direclty in | ||
| 129 | your HTML, and have them rendered dynamically. A minimal example | ||
| 130 | looks like this: | ||
| 131 | |||
| 132 | ``` | ||
| 133 | <!doctype html> | ||
| 134 | <head> | ||
| 135 | <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"> | ||
| 136 | </script> | ||
| 137 | </head> | ||
| 138 | |||
| 139 | <body> | ||
| 140 | <p>Hello! \[ e^{\pi i} + 1 = 0 \]</p> | ||
| 141 | </body> | ||
| 142 | ``` | ||
| 143 | |||
| 144 | In the example above I am including the MathJax library directly from a | ||
| 145 | URL. This means every time you load that page, a request is sent from | ||
| 146 | your browser to the MathJax server to get the code for rendering the | ||
| 147 | formulas. Among other things, this implies that my slides are going | ||
| 148 | to be dependent on this external website, and that they won't work | ||
| 149 | offline. The horror! | ||
| 150 | |||
| 151 | In theory I could install MathJax locally (or on my server) and get rid | ||
| 152 | of this dependency, and maybe at some point I'll do it. But for now | ||
| 153 | it is just easier and faster to include the script like this. And while | ||
| 154 | I was at it, I doubled down on the remote library thing and included | ||
| 155 | also [highlight.js](https://highlightjs.org), | ||
| 156 | a package for rendering code blocks with syntax highlighting. | ||
| 157 | |||
| 158 | ### Scrolling with JavaScript | ||
| 159 | |||
| 160 | The other big feature I wanted for the slides was for them to look and | ||
| 161 | behave like actual slides. So the whole HTML page should be divided into | ||
| 162 | single frames, and I wanted to be able to move back and forth between | ||
| 163 | frames by clicking or pressing a key. | ||
| 164 | |||
| 165 | In order to do this, I had to write my first piece of JavaScript. | ||
| 166 | The main part looks more or less like this: | ||
| 167 | |||
| 168 | ``` | ||
| 169 | const slides = document.querySelectorAll(".slide"); | ||
| 170 | |||
| 171 | const keysNext = ["ArrowRight", "ArrowDown", " "]; | ||
| 172 | const keysPrev = ["ArrowLeft", "ArrowUp"]; | ||
| 173 | |||
| 174 | // Disable default action of the navigation keys (e.g. scrolling). | ||
| 175 | document.addEventListener("keydown", function(e) { | ||
| 176 | if (keysNext.includes(e.key) || keysPrev.includes(e.key)) { | ||
| 177 | e.preventDefault(); | ||
| 178 | } | ||
| 179 | }); | ||
| 180 | |||
| 181 | function goto(slide) { | ||
| 182 | slide.focus(); | ||
| 183 | slide.scrollIntoView({ | ||
| 184 | behavior: "instant", | ||
| 185 | block: "start" | ||
| 186 | }); | ||
| 187 | } | ||
| 188 | |||
| 189 | function onkeydown(i, e) { | ||
| 190 | if (keysNext.includes(e.key) && i+1 < slides.length) { | ||
| 191 | goto(slides[i+1]); | ||
| 192 | } | ||
| 193 | if (keysPrev.includes(e.key) && i > 0) { | ||
| 194 | goto(slides[i-1]); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | function onclick(i, e) { | ||
| 199 | const w = slides[i].offsetWidth; | ||
| 200 | const x = e.clientX; | ||
| 201 | |||
| 202 | if (x > w/2 && i+1 < slides.length) { | ||
| 203 | goto(slides[i+1]); | ||
| 204 | } | ||
| 205 | if (x < w/2 && i > 0) { | ||
| 206 | goto(slides[i-1]); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | for (let i = 0; i < slides.length; i++) { | ||
| 211 | slides[i].addEventListener("keydown", e => onkeydown(i, e)); | ||
| 212 | slides[i].addEventListener("click", e => onclick(i, e)); | ||
| 213 | } | ||
| 214 | |||
| 215 | goto(slides[0]); // Go to the first slide when the presentation starts | ||
| 216 | ``` | ||
| 217 | |||
| 218 | First of all, every slide is a `div` with `class="slide"`. This allows | ||
| 219 | me to select all the slides with `document.querySelectorAll(".slide")`. | ||
| 220 | Then, after disabling any default handling of the arrows and space keys, | ||
| 221 | I add a new event listeners to every slide. These listeners uses the | ||
| 222 | `scrollIntoView()` function to scroll to the next or previous slide. | ||
| 223 | The `onclick()` function similarly handles clicks, where a click on the | ||
| 224 | left half of the screen goes to the previous slide and a click on the | ||
| 225 | right half goes to the next one. | ||
| 226 | |||
| 227 | And by the way, highjacking the default scrolling behavior is another | ||
| 228 | trend of modern web development that I hate. By I am fine with using | ||
| 229 | it here, because these slides are not meant to be a regular web page. | ||
| 230 | |||
| 231 | I also a function to add a footer to every slide: | ||
| 232 | |||
| 233 | ``` | ||
| 234 | function slideFooter() { | ||
| 235 | const start = "<div class=\"footer\"><table class=\"footer-table\"><tr>"; | ||
| 236 | const title = "Elliptic Curves and the ECM algorithm" | ||
| 237 | const link = "<a href=https://tronto.net/talks/ecm>tronto.net/talks/ecm</a>"; | ||
| 238 | const end = "</tr></table></div>"; | ||
| 239 | const content = | ||
| 240 | "<td class=\"footer-title\">" + title + "</td>" + | ||
| 241 | "<td class=\"footer-link\">" + link + "</td>"; | ||
| 242 | |||
| 243 | return start + content + end; | ||
| 244 | } | ||
| 245 | |||
| 246 | // In the main loop: | ||
| 247 | // slides[i].innerHTML += slideFooter() | ||
| 248 | ``` | ||
| 249 | |||
| 250 | In an older version I also had a small slide counter in the footer, | ||
| 251 | but I decided not to use it in the end. | ||
| 252 | |||
| 253 | Of course there was also some CSS work to | ||
| 254 | do. A new thing I learned in this regard is the | ||
| 255 | [flex](https://developer.mozilla.org/en-US/docs/Web/CSS/flex) | ||
| 256 | layout property, with which I was able to easily arrange | ||
| 257 | pieces of text and pictures in the slides - shoutout to | ||
| 258 | my friend [Jared](https://guissmo.com) for telling me about | ||
| 259 | it. Apart from this I don't have anything interesting to comment | ||
| 260 | about the CSS part of the slides. You can check the full code | ||
| 261 | [here](https://git.tronto.net/ecm/file/index.html.html) if you want; | ||
| 262 | everything is in a single HTML file. | ||
| 263 | |||
| 264 | The result looks fine, but it does not work perfectly will every screen | ||
| 265 | resolution. It's fine in 4:3 or 16:9, but with wider screens your | ||
| 266 | mileage may vary. I could improve it and always use the device height | ||
| 267 | (or width, but not both) as a reference. But this is quite some work | ||
| 268 | for very little gain, and in the end all I care about is that I can | ||
| 269 | show these slides from my laptop. I am sorry if you are viewing this | ||
| 270 | presentation from a smartphone. | ||
| 271 | |||
| 272 | You can view the slides | ||
| 273 | [on this page](https://sebastiano.tronto.net/talks/ecm). | ||
| 274 | |||
| 275 | ## Conclusion | ||
| 276 | |||
| 277 | I didn't need to do all this work for this presentation, but it was fun to | ||
| 278 | learn new stuff - not only for the C++ part, that I did not end up using | ||
| 279 | anyway, but also for the slides. It's good to know a bit of JavaScript, | ||
| 280 | even if I don't plan to use it much in the future. | ||
| 281 | |||
| 282 | I scheduled this post to go online on the same day as my presentation - | ||
| 283 | wish me good luck :) | ||
diff --git a/src/talks/ecm/images/beer.jpg b/src/talks/ecm/images/beer.jpg new file mode 100644 index 0000000..5a67225 --- /dev/null +++ b/src/talks/ecm/images/beer.jpg | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/clock.png b/src/talks/ecm/images/clock.png new file mode 100644 index 0000000..631ee42 --- /dev/null +++ b/src/talks/ecm/images/clock.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/clock2.png b/src/talks/ecm/images/clock2.png new file mode 100644 index 0000000..bc2706b --- /dev/null +++ b/src/talks/ecm/images/clock2.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/demo.jpg b/src/talks/ecm/images/demo.jpg new file mode 100644 index 0000000..eaf2cd9 --- /dev/null +++ b/src/talks/ecm/images/demo.jpg | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/ec1.png b/src/talks/ecm/images/ec1.png new file mode 100644 index 0000000..1c31a1e --- /dev/null +++ b/src/talks/ecm/images/ec1.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/ec2.png b/src/talks/ecm/images/ec2.png new file mode 100644 index 0000000..c44f3c0 --- /dev/null +++ b/src/talks/ecm/images/ec2.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/ec3.png b/src/talks/ecm/images/ec3.png new file mode 100644 index 0000000..6db47e4 --- /dev/null +++ b/src/talks/ecm/images/ec3.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/euclid.png b/src/talks/ecm/images/euclid.png new file mode 100644 index 0000000..ccfec81 --- /dev/null +++ b/src/talks/ecm/images/euclid.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/factorization.webp b/src/talks/ecm/images/factorization.webp new file mode 100644 index 0000000..892a53d --- /dev/null +++ b/src/talks/ecm/images/factorization.webp | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/number-line.png b/src/talks/ecm/images/number-line.png new file mode 100644 index 0000000..27531cb --- /dev/null +++ b/src/talks/ecm/images/number-line.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/numbers.jpg b/src/talks/ecm/images/numbers.jpg new file mode 100644 index 0000000..9b0f835 --- /dev/null +++ b/src/talks/ecm/images/numbers.jpg | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/questions.png b/src/talks/ecm/images/questions.png new file mode 100644 index 0000000..eee3df2 --- /dev/null +++ b/src/talks/ecm/images/questions.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-1a.png b/src/talks/ecm/images/sum-1a.png new file mode 100644 index 0000000..61fb531 --- /dev/null +++ b/src/talks/ecm/images/sum-1a.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-1b.png b/src/talks/ecm/images/sum-1b.png new file mode 100644 index 0000000..f3a7972 --- /dev/null +++ b/src/talks/ecm/images/sum-1b.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-1c.png b/src/talks/ecm/images/sum-1c.png new file mode 100644 index 0000000..c534cce --- /dev/null +++ b/src/talks/ecm/images/sum-1c.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-2a.png b/src/talks/ecm/images/sum-2a.png new file mode 100644 index 0000000..d925e7a --- /dev/null +++ b/src/talks/ecm/images/sum-2a.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-2b.png b/src/talks/ecm/images/sum-2b.png new file mode 100644 index 0000000..dbd6f03 --- /dev/null +++ b/src/talks/ecm/images/sum-2b.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-2c.png b/src/talks/ecm/images/sum-2c.png new file mode 100644 index 0000000..4637bb8 --- /dev/null +++ b/src/talks/ecm/images/sum-2c.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-3a.png b/src/talks/ecm/images/sum-3a.png new file mode 100644 index 0000000..f85d7ff --- /dev/null +++ b/src/talks/ecm/images/sum-3a.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-3b.png b/src/talks/ecm/images/sum-3b.png new file mode 100644 index 0000000..537c5b2 --- /dev/null +++ b/src/talks/ecm/images/sum-3b.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-3c.png b/src/talks/ecm/images/sum-3c.png new file mode 100644 index 0000000..ca093dc --- /dev/null +++ b/src/talks/ecm/images/sum-3c.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-4a.png b/src/talks/ecm/images/sum-4a.png new file mode 100644 index 0000000..82eee13 --- /dev/null +++ b/src/talks/ecm/images/sum-4a.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-4b.png b/src/talks/ecm/images/sum-4b.png new file mode 100644 index 0000000..827c0c2 --- /dev/null +++ b/src/talks/ecm/images/sum-4b.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/images/sum-4c.png b/src/talks/ecm/images/sum-4c.png new file mode 100644 index 0000000..bf323fd --- /dev/null +++ b/src/talks/ecm/images/sum-4c.png | |||
| Binary files differ | |||
diff --git a/src/talks/ecm/index.html.raw b/src/talks/ecm/index.html.raw new file mode 100644 index 0000000..cf168b7 --- /dev/null +++ b/src/talks/ecm/index.html.raw | |||
| @@ -0,0 +1,622 @@ | |||
| 1 | <!doctype html> | ||
| 2 | <html lang="en"> | ||
| 3 | <head> | ||
| 4 | <title>Elliptic Curves and the ECM algorithm</title> | ||
| 5 | <meta name="viewport" content="width=device-width" /> | ||
| 6 | |||
| 7 | <!-- Import MathJax script --> | ||
| 8 | <script id="MathJax-script" async src= | ||
| 9 | "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" | ||
| 10 | ></script> | ||
| 11 | |||
| 12 | <!-- Import highlight.js script and style sheet --> | ||
| 13 | <script id="highlight.js" src=" | ||
| 14 | https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" | ||
| 15 | ></script> | ||
| 16 | <link rel="stylesheet" href=" | ||
| 17 | https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/vs.css" | ||
| 18 | > | ||
| 19 | |||
| 20 | <!-- Custom style --> | ||
| 21 | <style> | ||
| 22 | html { height: 100vh; width: 98vw; margin: auto; font-family: sans-serif; } | ||
| 23 | h1 { font-size: 3.5vw; background-color: #eeeeee; margin: 0; } | ||
| 24 | body { font-size: 2.2vw; height: 100%; width: 100%; } | ||
| 25 | a, a:visited { color: #0f2899; text-decoration: none; } | ||
| 26 | a:hover { text-decoration: underline; } | ||
| 27 | figcaption { text-align: center; font-size: 1.5vw; } | ||
| 28 | em { font-style: normal; color: blue; } | ||
| 29 | |||
| 30 | .slide { outline: none; height: 100vh; width: 100%; } | ||
| 31 | .slide { | ||
| 32 | display: flex; | ||
| 33 | flex-direction: column; | ||
| 34 | justify-content: space-between; | ||
| 35 | } | ||
| 36 | .slide ul { margin-left: 1.5vw; } | ||
| 37 | .slide ol { margin-left: 1.5vw; } | ||
| 38 | .slide p { margin-left: 1.5vw; } | ||
| 39 | |||
| 40 | .slide.titlepage p, a { text-align: center; } | ||
| 41 | .slide.titlepage span.title { font-size: 3.6vw; font-weight: bold; } | ||
| 42 | .slide.titlepage span.author { } | ||
| 43 | |||
| 44 | .slide.ecsum img { width: 50%; display: block; margin: auto; } | ||
| 45 | |||
| 46 | .slide div.centertext { text-align: center; margin: auto; width: 60%; } | ||
| 47 | |||
| 48 | .columns { | ||
| 49 | display: flex; | ||
| 50 | flex-direction: row; | ||
| 51 | justify-content: space-between; | ||
| 52 | align-items: center; | ||
| 53 | } | ||
| 54 | |||
| 55 | .footer { font-size: 1.8vw; background-color: #eeeeee; } | ||
| 56 | .footer table { width: 100%; } | ||
| 57 | .footer-title { font-weight: bold; } | ||
| 58 | .footer-link { text-align: right; } | ||
| 59 | </style> | ||
| 60 | <meta charset="utf-8"> | ||
| 61 | </head> | ||
| 62 | |||
| 63 | <body> | ||
| 64 | |||
| 65 | <div class="slide titlepage" tabindex="-1" | ||
| 66 | style="background-image: url('images/sum-2c.png'); | ||
| 67 | background-position: center; | ||
| 68 | background-repeat: no-repeat; | ||
| 69 | background-size: 70%; | ||
| 70 | background-color: rgba(255, 255, 255, 0.85); | ||
| 71 | background-blend-mode: overlay;"> | ||
| 72 | |||
| 73 | <p></p> | ||
| 74 | |||
| 75 | <p><span class="title">Elliptic curves and the ECM algorithm<span></p> | ||
| 76 | <p><span class="author">Sebastiano Tronto<span></p> | ||
| 77 | <p><span class="event">ALTEN Scientific Software Evening<span></p> | ||
| 78 | |||
| 79 | </div> | ||
| 80 | |||
| 81 | <div class="slide titlepage" tabindex="-1" | ||
| 82 | style="background-image: url('images/numbers.jpg'); | ||
| 83 | background-position: center; | ||
| 84 | background-repeat: no-repeat; | ||
| 85 | background-size: 100%; | ||
| 86 | background-color: rgba(255, 255, 255, 0.75); | ||
| 87 | background-blend-mode: overlay;"> | ||
| 88 | <p></p> | ||
| 89 | <p><span class="title">Part I: Numbers<span></p> | ||
| 90 | <p></p> | ||
| 91 | </div> | ||
| 92 | |||
| 93 | <div class="slide" tabindex="-1"> | ||
| 94 | <h1>The integers</h1> | ||
| 95 | |||
| 96 | <img alt="The number line" src="images/number-line.png" | ||
| 97 | style="width: 70%; margin-left: 15%; margin-right: 15%;"/> | ||
| 98 | |||
| 99 | <ul> | ||
| 100 | <li>Operations: sum \(+\), difference \(-\) and multiplication \(\times\)</li> | ||
| 101 | <li>Various properties: associativity, commutativity, etc...</li> | ||
| 102 | <li>What about division (without remainder)?<br> | ||
| 103 | If <tt>\(\frac ab\)</tt> is an integer we say that | ||
| 104 | <tt>\(a\)</tt><em> divides </em><tt>\(b\)</tt> (in code: | ||
| 105 | <tt>a % b == 0</tt>)</li> | ||
| 106 | </ul> | ||
| 107 | </div> | ||
| 108 | |||
| 109 | <div class="slide" tabindex="-1"> | ||
| 110 | <h1>The integers modulo N</h1> | ||
| 111 | |||
| 112 | <div class="columns"> | ||
| 113 | |||
| 114 | <ul> | ||
| 115 | <!-- li>Integers modulo <tt>N</tt>: the possible remainders of | ||
| 116 | division by <tt>N</tt><br--> | ||
| 117 | <li>Two numbers are the same if they give the <em>same remainder</em> | ||
| 118 | when divided by <tt>N</tt></li> | ||
| 119 | <li>Think of <tt>int</tt>, but with <tt>% N</tt> | ||
| 120 | after every operation</li> | ||
| 121 | <li>Examples with \(N=12\): | ||
| 122 | \[9+5\equiv 14\equiv 2\pmod{12}\] | ||
| 123 | \[7-11\equiv-4\equiv 8\pmod{12}\] | ||
| 124 | \[3\times 4\equiv 12\equiv 0\pmod{12}\] | ||
| 125 | </li> | ||
| 126 | </ul> | ||
| 127 | |||
| 128 | <img alt="The number clock" src="images/clock.png" | ||
| 129 | style="width: 35%;"/> | ||
| 130 | |||
| 131 | </div> | ||
| 132 | |||
| 133 | </div> | ||
| 134 | |||
| 135 | <div class="slide" tabindex="-1"> | ||
| 136 | <h1>The integers modulo N - Division</h1> | ||
| 137 | |||
| 138 | <p style="text-align: center;"><strong>What about division?</strong></p> | ||
| 139 | |||
| 140 | <ul> | ||
| 141 | <li> | ||
| 142 | Sometimes it works | ||
| 143 | \[ | ||
| 144 | \frac 37\equiv 9 \pmod{12} \qquad | ||
| 145 | \text{because} \qquad 9\times 7 \equiv 63 \equiv 3 \pmod{12} | ||
| 146 | \] | ||
| 147 | </li> | ||
| 148 | |||
| 149 | <li> | ||
| 150 | Sometimes it does not | ||
| 151 | \[ | ||
| 152 | \frac 32\equiv \; ? \pmod{4} \qquad {\color{red}\text{Impossible!}} | ||
| 153 | \] | ||
| 154 | </li> | ||
| 155 | </ul> | ||
| 156 | </div> | ||
| 157 | |||
| 158 | <div class="slide" tabindex="-1"> | ||
| 159 | <h1>Integers modulo N - Division</h1> | ||
| 160 | |||
| 161 | <ul> | ||
| 162 | <li> | ||
| 163 | Sometimes it's... weird? | ||
| 164 | \[ | ||
| 165 | \frac 62 \equiv \; ? \pmod{8} \quad | ||
| 166 | \begin{array}{l} | ||
| 167 | \rightarrow {\color{red}3} \times 2 \equiv 6\pmod{8}\\ | ||
| 168 | \rightarrow {\color{red}7} \times 2 \equiv 14 \equiv 6 \pmod{8} | ||
| 169 | \end{array} | ||
| 170 | \] | ||
| 171 | </li> | ||
| 172 | </div> | ||
| 173 | |||
| 174 | <div class="slide" tabindex="-1"> | ||
| 175 | <h1>Integers modulo N - Division</h1> | ||
| 176 | <div class="columns"> | ||
| 177 | <ul> | ||
| 178 | <li>Can divide by \(a\) when \[\operatorname{GCD}(a, N)=1\]</li> | ||
| 179 | <li>With the | ||
| 180 | <a href="https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm"> | ||
| 181 | extended GCD algorithm</a> find \(x\) and \(y\) such that | ||
| 182 | \[ | ||
| 183 | ax+Ny=1 | ||
| 184 | \] | ||
| 185 | <li> | ||
| 186 | This means \(\frac{1}{a}\equiv x\pmod{N}\) | ||
| 187 | </li> | ||
| 188 | </ul> | ||
| 189 | <pre><code class="language-python" | ||
| 190 | style="border: 0.2vw solid; font-size: 2.2vw;"> | ||
| 191 | def extended_gcd(a, b): | ||
| 192 | if b == 0: | ||
| 193 | return a, 1, 0 | ||
| 194 | g, x, y = extended_gcd(b, a % b) | ||
| 195 | return g, y, x - y*(a // b) | ||
| 196 | </code></pre> | ||
| 197 | </div> | ||
| 198 | <p style="text-align: center;"> | ||
| 199 | Division always works if \(N\) is a <em>prime</em> number!</p> | ||
| 200 | </div> | ||
| 201 | |||
| 202 | <div class="slide" tabindex="-1"> | ||
| 203 | <h1>Modular arithmetic - recap</h1> | ||
| 204 | <div class="columns"> | ||
| 205 | <ul> | ||
| 206 | <li>Integers modulo \(N\) are (almost) like numbers</li> | ||
| 207 | <li>Normal operations like \(+\), \(-\) and \(\times\) work</li> | ||
| 208 | <li>Division sometimes works, sometimes not</li> | ||
| 209 | <li>Division always works if \(N\) is <em>prime</em></li> | ||
| 210 | </ul> | ||
| 211 | <img alt="The number line" src="images/clock2.png" style="width: 40%;"/> | ||
| 212 | </div> | ||
| 213 | </div> | ||
| 214 | |||
| 215 | <div class="slide titlepage" tabindex="-1" | ||
| 216 | style="background-image: url('images/sum-2c.png'); | ||
| 217 | background-position: center; | ||
| 218 | background-repeat: no-repeat; | ||
| 219 | background-size: 70%; | ||
| 220 | background-color: rgba(255, 255, 255, 0.85); | ||
| 221 | background-blend-mode: overlay;"> | ||
| 222 | <p></p> | ||
| 223 | <p><span class="title">Part II: Elliptic Curves<span></p> | ||
| 224 | <p></p> | ||
| 225 | </div> | ||
| 226 | |||
| 227 | <div class="slide" tabindex="-1"> | ||
| 228 | <h1>Elliptic curves</h1> | ||
| 229 | |||
| 230 | <div class="columns"> | ||
| 231 | |||
| 232 | <p> | ||
| 233 | An <em>elliptic curve</em> is a curve with equation | ||
| 234 | \[ y^2 = x^3+Ax+B \] | ||
| 235 | Where \(A\) and \(B\) are numbers with \[4A^3+27B^2\neq 0\] | ||
| 236 | </p> | ||
| 237 | |||
| 238 | <figure style="width: 45%;"> | ||
| 239 | <figcaption>\(y^2=x^3-x+1\) <br> \((A=-1, B=1\))</figcaption> | ||
| 240 | <img alt="An elliptic curve" src="images/ec1.png" style="width: 100%;"/> | ||
| 241 | </figure> | ||
| 242 | |||
| 243 | </div> | ||
| 244 | </div> | ||
| 245 | |||
| 246 | <div class="slide" tabindex="-1"> | ||
| 247 | <h1>Elliptic curves</h1> | ||
| 248 | |||
| 249 | <div class="columns"> | ||
| 250 | |||
| 251 | <figure style="width: 45%;"> | ||
| 252 | <figcaption>\(y^2=x^3+13x-34\) <br> \((A=13, B=-34\))</figcaption> | ||
| 253 | <img alt="An elliptic curve" src="images/ec3.png" style="width: 100%;"/> | ||
| 254 | </figure> | ||
| 255 | |||
| 256 | <figure style="width: 45%;"> | ||
| 257 | <figcaption>\(y^2=x^3-x\) <br> \((A=-1, B=0\))</figcaption> | ||
| 258 | <img alt="An elliptic curve" src="images/ec2.png" style="width: 100%;"/> | ||
| 259 | </figure> | ||
| 260 | |||
| 261 | </div> | ||
| 262 | </div> | ||
| 263 | |||
| 264 | <div class="slide" tabindex="-1"> | ||
| 265 | <h1>Elliptic curves</h1> | ||
| 266 | |||
| 267 | <div class="columns"> | ||
| 268 | <ul> | ||
| 269 | <li>There is a "sum" operation for points of a curve | ||
| 270 | (NOT the sum of coordinates)</li> | ||
| 271 | <li>To make things work out nicely, we pretend the curve has | ||
| 272 | a <em>point at infinity</em> that acts as \(0\): | ||
| 273 | \[P+0=0\qquad 0+P=0\qquad P-P=0\]</li> | ||
| 274 | </ul> | ||
| 275 | |||
| 276 | <img alt="Elliptic curve sum" src="images/sum-2c.png" style="width: 80%;"/> | ||
| 277 | |||
| 278 | </div> | ||
| 279 | </div> | ||
| 280 | |||
| 281 | <div class="slide ecsum" tabindex="-1"> | ||
| 282 | <h1>Elliptic curves - sum operation - example 1</h2> | ||
| 283 | <img alt="Elliptic curve sum" src="images/sum-2a.png"/> | ||
| 284 | </div> | ||
| 285 | <div class="slide ecsum" tabindex="-1"> | ||
| 286 | <h1>Elliptic curves - sum operation - example 1</h2> | ||
| 287 | <img alt="Elliptic curve sum" src="images/sum-2b.png"/> | ||
| 288 | </div> | ||
| 289 | <div class="slide ecsum" tabindex="-1"> | ||
| 290 | <h1>Elliptic curves - sum operation - example 1</h2> | ||
| 291 | <img alt="Elliptic curve sum" src="images/sum-2c.png"/> | ||
| 292 | </div> | ||
| 293 | |||
| 294 | <div class="slide ecsum" tabindex="-1"> | ||
| 295 | <h1>Elliptic curves - sum operation - example 2</h2> | ||
| 296 | <img alt="Elliptic curve sum" src="images/sum-3a.png"/> | ||
| 297 | </div> | ||
| 298 | <div class="slide ecsum" tabindex="-1"> | ||
| 299 | <h1>Elliptic curves - sum operation - example 2</h2> | ||
| 300 | <img alt="Elliptic curve sum" src="images/sum-3b.png"/> | ||
| 301 | </div> | ||
| 302 | <div class="slide ecsum" tabindex="-1"> | ||
| 303 | <h1>Elliptic curves - sum operation - example 2</h2> | ||
| 304 | <img alt="Elliptic curve sum" src="images/sum-3c.png"/> | ||
| 305 | </div> | ||
| 306 | |||
| 307 | <div class="slide ecsum" tabindex="-1"> | ||
| 308 | <h1>Elliptic curves - sum operation - example 3</h2> | ||
| 309 | <img alt="Elliptic curve sum" src="images/sum-4a.png"/> | ||
| 310 | </div> | ||
| 311 | <div class="slide ecsum" tabindex="-1"> | ||
| 312 | <h1>Elliptic curves - sum operation - example 3</h2> | ||
| 313 | <img alt="Elliptic curve sum" src="images/sum-4b.png"/> | ||
| 314 | </div> | ||
| 315 | <div class="slide ecsum" tabindex="-1"> | ||
| 316 | <h1>Elliptic curves - sum operation - example 3</h2> | ||
| 317 | <img alt="Elliptic curve sum" src="images/sum-4c.png"/> | ||
| 318 | </div> | ||
| 319 | |||
| 320 | <div class="slide" tabindex="-1"> | ||
| 321 | <h1>Elliptic curves - sum operation - code</h1> | ||
| 322 | |||
| 323 | <div class="columns"> | ||
| 324 | <pre><code class="language-python" | ||
| 325 | style="font-size: 2.8vh;"> | ||
| 326 | # Computes p+q on the elliptic curve y^2 = x^3 + Ax + B | ||
| 327 | def ec_sum(p: Point, q: Point, A: double) -> Point: | ||
| 328 | if p.is_zero: | ||
| 329 | return q | ||
| 330 | if q.is_zero: | ||
| 331 | return p | ||
| 332 | if p.x == q.x and p.y == -q.y: | ||
| 333 | return Point(is_zero = True) | ||
| 334 | |||
| 335 | if p.x != q.x: | ||
| 336 | k = (p.y - q.y) / (p.x - q.x) | ||
| 337 | else: | ||
| 338 | k = (3 * p.x**2 + A) / (p.y + q.y) | ||
| 339 | |||
| 340 | new_x = k**2 - p.x - q.x | ||
| 341 | new_y = k * (p.x - new_x) - p.y | ||
| 342 | return Point(x = new_x, y = new_y) | ||
| 343 | </code></pre> | ||
| 344 | |||
| 345 | <pre><code class="language-python" | ||
| 346 | style="border: 0.2vw solid; font-size: 2.8vh;"> | ||
| 347 | @dataclass | ||
| 348 | class Point: | ||
| 349 | x: int = 0 | ||
| 350 | y: int = 0 | ||
| 351 | is_zero: bool = False | ||
| 352 | </code></pre> | ||
| 353 | |||
| 354 | </div> | ||
| 355 | </div> | ||
| 356 | |||
| 357 | <div class="slide" tabindex="-1"> | ||
| 358 | <h1>Elliptic curves - recap</h1> | ||
| 359 | <div class="columns"> | ||
| 360 | <ul> | ||
| 361 | <li>Curves of equation \(y^2=x^3+Ax+B\)</li> | ||
| 362 | <li>Can "sum" points of the same curve</li> | ||
| 363 | <li>Nice properties: associativity, commutativity...</li> | ||
| 364 | <li>The sum operation can be easily implemented</li> | ||
| 365 | </ul> | ||
| 366 | <img alt="The number line" src="images/sum-2c.png" style="width: 40%;"/> | ||
| 367 | </div> | ||
| 368 | </div> | ||
| 369 | |||
| 370 | <div class="slide titlepage" tabindex="-1" | ||
| 371 | style="background-image: url('images/factorization.webp'); | ||
| 372 | background-position: center; | ||
| 373 | background-repeat: no-repeat; | ||
| 374 | background-size: 50%; | ||
| 375 | background-color: rgba(255, 255, 255, 0.90); | ||
| 376 | background-blend-mode: overlay;"> | ||
| 377 | <p></p> | ||
| 378 | <p><span class="title">Part III: The Elliptic Curve Factorization Method<span></p> | ||
| 379 | <p></p> | ||
| 380 | </div> | ||
| 381 | |||
| 382 | <div class="slide" tabindex="-1"> | ||
| 383 | <h1>Integer factorization</h1> | ||
| 384 | <p style="text-align: center;"><strong> | ||
| 385 | Every positive integer can be written as the product of prime numbers | ||
| 386 | </strong></p> | ||
| 387 | <div class="columns"> | ||
| 388 | <ul> | ||
| 389 | <li>Example: \(69420 = 2\times 2\times 3\times 5\times 13\times 89\)</li> | ||
| 390 | <li>Computationally hard</li> | ||
| 391 | <li>Important for cryptography!</li> | ||
| 392 | </ul> | ||
| 393 | <img src="images/euclid.png" style="height: 60vh;"/> | ||
| 394 | </div> | ||
| 395 | </div> | ||
| 396 | |||
| 397 | <div class="slide" tabindex="-1"> | ||
| 398 | <h1>Integer factorization - high-level procedure</h1> | ||
| 399 | |||
| 400 | <div class="columns"> | ||
| 401 | <pre><code class="language-python" | ||
| 402 | style="border: 0.2vw solid; font-size: 1.4vw;"> | ||
| 403 | # Returns the list of prime factors of n | ||
| 404 | def factorize(n: int) -> list: | ||
| 405 | if n == 1: | ||
| 406 | return [] | ||
| 407 | |||
| 408 | if is_prime(n): | ||
| 409 | return [n] | ||
| 410 | |||
| 411 | f = find_factor(n) | ||
| 412 | |||
| 413 | return factorize(n) + factorize(n//f) | ||
| 414 | </code></pre> | ||
| 415 | |||
| 416 | <ul> | ||
| 417 | <li><tt>is_prime(n)</tt> can be implemented | ||
| 418 | efficiently | ||
| 419 | (<a href="https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test">Miller-Rabin</a>, | ||
| 420 | <a href="https://en.wikipedia.org/wiki/AKS_primality_test">AKS</a> | ||
| 421 | or <a href="https://en.wikipedia.org/wiki/Elliptic_curve_primality">ECPP</a>) | ||
| 422 | </li> | ||
| 423 | <li>Naive implementation of <tt>find_factor(n):</tt> | ||
| 424 | <pre><code class="language-python" style="font-size: 2vw;"> | ||
| 425 | def find_factor(n: int) -> int: | ||
| 426 | for i in range(2,floor(sqrt(n))+1): | ||
| 427 | if n % i == 0: | ||
| 428 | return i | ||
| 429 | </code></pre> | ||
| 430 | </li> | ||
| 431 | </ul> | ||
| 432 | |||
| 433 | </div> | ||
| 434 | </div> | ||
| 435 | |||
| 436 | <div class="slide" tabindex="-1"> | ||
| 437 | <h1>Find Factor - Elliptic Curve Method</h1> | ||
| 438 | <div> | ||
| 439 | <p><strong>To find a factor of \(n\):</strong><p> | ||
| 440 | <ol> | ||
| 441 | <li>Take a random Elliptic Curve \(E\) | ||
| 442 | and a random point \(P\) of \(E\)</li> | ||
| 443 | <li>Take a <em>suitable number \(m\)</em></li> | ||
| 444 | <li>Try to compute \(m\cdot P = P+P+\cdots+P\quad\) (\(m\) times) | ||
| 445 | with <em>coordinates modulo \(n\)</em></li> | ||
| 446 | <li>If you attempt an <em>impossible division</em> by some number \(d\), | ||
| 447 | <em>return \(\operatorname{GCD}(n,d)\)</em></li> | ||
| 448 | <li>Go back to 1.</li> | ||
| 449 | </ol> | ||
| 450 | </div> | ||
| 451 | </div> | ||
| 452 | |||
| 453 | <div class="slide" tabindex="-1" style="font-size: 2vw;"> | ||
| 454 | <h1>Find Factor - Elliptic Curve Method - Example</h1> | ||
| 455 | <ul> | ||
| 456 | <li>Take \(n = 91\)</li> | ||
| 457 | <li>Take \(E: y^2 = x^3 + 51x -371\) and \(P = (11, 39)\) and \(M = 2\)</li> | ||
| 458 | <li> | ||
| 459 | Try to compute \(M\cdot P=P+P\pmod n\): | ||
| 460 | \[ k = \frac{3x_p^2+51}{2y_p} \pmod n\] | ||
| 461 | Is \(2y_p=78\) invertible modulo \(91\)? | ||
| 462 | \[ \operatorname{GCD}(78, 91) = 13 \neq 1 \quad \implies \quad \text{NO!} \] | ||
| 463 | </li> | ||
| 464 | <li>Found factor: \(13\)</li> | ||
| 465 | </div> | ||
| 466 | |||
| 467 | <div class="slide titlepage" tabindex="-1" | ||
| 468 | style="background-image: url('images/demo.jpg'); | ||
| 469 | background-position: center; | ||
| 470 | background-repeat: no-repeat; | ||
| 471 | background-size: 100%; | ||
| 472 | background-color: rgba(255, 255, 255, 0.60); | ||
| 473 | background-blend-mode: overlay;"> | ||
| 474 | <p></p> | ||
| 475 | <p><span class="title">Demo time!<span></p> | ||
| 476 | <a href="https://git.tronto.net/ecm">git.tronto.net/ecm</a> | ||
| 477 | <p></p> | ||
| 478 | </div> | ||
| 479 | |||
| 480 | <div class="slide" tabindex="-1"> | ||
| 481 | <h1>Elliptic Curve Method - Questions</h1> | ||
| 482 | <div class="centertext"> | ||
| 483 | <p><strong> | ||
| 484 | Q: Aren't we just computing the \(\operatorname{GCD}\) with random numbers? | ||
| 485 | </strong></p> | ||
| 486 | <p> | ||
| 487 | A: Yes, but Elliptic Curve operations produce "good candidates" | ||
| 488 | for these random numbers. | ||
| 489 | </p> | ||
| 490 | </div> | ||
| 491 | </div> | ||
| 492 | |||
| 493 | <div class="slide" tabindex="-1"> | ||
| 494 | <h1>Elliptic Curve Method - Questions</h1> | ||
| 495 | <div class="centertext"> | ||
| 496 | <p><strong>Q: Can we do the same without elliptic curves?</strong></p> | ||
| 497 | <p>A: Yes, with | ||
| 498 | <a href="https://en.wikipedia.org/wiki/Pollard%27s_p_%E2%88%92_1_algorithm"> | ||
| 499 | Pollard's \(p-1\) Algorithm</a>, but ECM is faster.</p> | ||
| 500 | </div> | ||
| 501 | </div> | ||
| 502 | |||
| 503 | <div class="slide" tabindex="-1"> | ||
| 504 | <h1>Elliptic Curve Method - Questions</h1> | ||
| 505 | <div class="centertext"> | ||
| 506 | <p><strong> | ||
| 507 | Q: Are there objects that are more complicated than Elliptic Curves | ||
| 508 | and can make the method even faster? | ||
| 509 | </strong></p> | ||
| 510 | <p>A: Yes, there are higher-dimensional | ||
| 511 | <a href="https://en.wikipedia.org/wiki/Abelian_variety"> | ||
| 512 | Abelian Varieties</a> and other | ||
| 513 | <a href="https://en.wikipedia.org/wiki/Algebraic_group"> | ||
| 514 | Algebraic Groups</a>, but they are much harder (if not impossible) | ||
| 515 | to implement efficiently.</p> | ||
| 516 | </div> | ||
| 517 | </div> | ||
| 518 | |||
| 519 | <div class="slide titlepage" tabindex="-1" | ||
| 520 | style="background-image: url('images/questions.png'); | ||
| 521 | background-position: center; | ||
| 522 | background-repeat: no-repeat; | ||
| 523 | background-size: 60%; | ||
| 524 | background-color: rgba(255, 255, 255, 0.85); | ||
| 525 | background-blend-mode: overlay;"> | ||
| 526 | <p></p> | ||
| 527 | <p><span class="title">More questions?<span></p> | ||
| 528 | <p></p> | ||
| 529 | </div> | ||
| 530 | |||
| 531 | <div class="slide titlepage" tabindex="-1" | ||
| 532 | style="background-image: url('images/beer.jpg'); | ||
| 533 | background-position: center; | ||
| 534 | background-repeat: no-repeat; | ||
| 535 | background-size: 80%; | ||
| 536 | background-color: rgba(255, 255, 255, 0.65); | ||
| 537 | background-blend-mode: overlay;"> | ||
| 538 | <p></p> | ||
| 539 | <p><span class="title">Drinks!<span></p> | ||
| 540 | <p></p> | ||
| 541 | </div> | ||
| 542 | |||
| 543 | <script> | ||
| 544 | // The list of all slides of the presentation. | ||
| 545 | const slides = document.querySelectorAll(".slide"); | ||
| 546 | |||
| 547 | // Navigation keys. | ||
| 548 | const keysNext = ["ArrowRight", "ArrowDown", " "]; | ||
| 549 | const keysPrev = ["ArrowLeft", "ArrowUp"]; | ||
| 550 | |||
| 551 | // Function to move to a given slide. | ||
| 552 | // This also focuses the slide, so any key press will be | ||
| 553 | // handled by the correct slide's event handler. | ||
| 554 | function goto(slide) { | ||
| 555 | slide.focus(); | ||
| 556 | slide.scrollIntoView({ | ||
| 557 | behavior: "instant", | ||
| 558 | block: "start" | ||
| 559 | }); | ||
| 560 | } | ||
| 561 | |||
| 562 | // Handle key press events. | ||
| 563 | function onkeydown(i, e) { | ||
| 564 | if (keysNext.includes(e.key) && i+1 < slides.length) { | ||
| 565 | goto(slides[i+1]); | ||
| 566 | } | ||
| 567 | if (keysPrev.includes(e.key) && i > 0) { | ||
| 568 | goto(slides[i-1]); | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 572 | // Handle click or tap events. | ||
| 573 | // Tapping on the right half of the screen scrolls forwards, | ||
| 574 | // tapping on the left half scrolls backwards. | ||
| 575 | function onclick(i, e) { | ||
| 576 | const w = slides[i].offsetWidth; | ||
| 577 | const x = e.clientX; | ||
| 578 | |||
| 579 | if (x > w/2 && i+1 < slides.length) { | ||
| 580 | goto(slides[i+1]); | ||
| 581 | } | ||
| 582 | if (x < w/2 && i > 0) { | ||
| 583 | goto(slides[i-1]); | ||
| 584 | } | ||
| 585 | } | ||
| 586 | |||
| 587 | // Disable default action of the navigation keys (e.g. scrolling). | ||
| 588 | document.addEventListener("keydown", function(e) { | ||
| 589 | if (keysNext.includes(e.key) || keysPrev.includes(e.key)) { | ||
| 590 | e.preventDefault(); | ||
| 591 | } | ||
| 592 | }); | ||
| 593 | |||
| 594 | // Function to add a footer to every slide. | ||
| 595 | function slideFooter() { | ||
| 596 | const start = "<div class=\"footer\"><table class=\"footer-table\"><tr>"; | ||
| 597 | const title = "Elliptic Curves and the ECM algorithm" | ||
| 598 | const link = "<a href=https://tronto.net/talks/ecm>tronto.net/talks/ecm</a>"; | ||
| 599 | const end = "</tr></table></div>"; | ||
| 600 | const content = | ||
| 601 | "<td class=\"footer-title\">" + title + "</td>" + | ||
| 602 | "<td class=\"footer-link\">" + link + "</td>"; | ||
| 603 | |||
| 604 | return start + content + end; | ||
| 605 | } | ||
| 606 | |||
| 607 | // Add slide footers and event handlers. | ||
| 608 | for (let i = 0; i < slides.length; i++) { | ||
| 609 | slides[i].innerHTML += slideFooter(); | ||
| 610 | slides[i].addEventListener("keydown", e => onkeydown(i, e)); | ||
| 611 | slides[i].addEventListener("click", e => onclick(i, e)); | ||
| 612 | } | ||
| 613 | |||
| 614 | // Focus and scroll into view the first slide. | ||
| 615 | goto(slides[0]); | ||
| 616 | |||
| 617 | // Call highlight.js | ||
| 618 | hljs.highlightAll(); | ||
| 619 | </script> | ||
| 620 | |||
| 621 | </body> | ||
| 622 | </html> | ||
diff --git a/src/talks/talks.md b/src/talks/talks.md index b7cea5b..595f49a 100644 --- a/src/talks/talks.md +++ b/src/talks/talks.md | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | 12 | ||
| 13 | ## Math | 13 | ## Math |
| 14 | 14 | ||
| 15 | * *Elliptic Curves and the ECM algorithm*. | ||
| 16 | ALTEN Scientific Software Evening, February 2025. | ||
| 17 | [Slides: [html, 2.4Mb](./ecm)] | ||
| 18 | |||
| 15 | * *Kummer theory for elliptic curves*. | 19 | * *Kummer theory for elliptic curves*. |
| 16 | Short talk for Tarrach Prize 2023, March 2023. | 20 | Short talk for Tarrach Prize 2023, March 2023. |
| 17 | [Slides: [pdf, 288Kb](kummer-tarrach.pdf)] | 21 | [Slides: [pdf, 288Kb](kummer-tarrach.pdf)] |
