The animated elliptic curve
curves.ulfheim.net
curves.ulfheim.net
If you want to keep going, as an advanced beginner I'd like to see:
Arbitrary bigint math - how do you do Exp/Sqrt with arbitrary sized ints? (I'm familiar with two crypto libs that do this, and MPIs & branches confuse me).
Second: why is C25519 faster than SecP256R1 or BrainPool? maybe some insight there? (Isn't Ed25519 the signature name? and X25519 the ECDH name?)
Greedy of me, but thanks!
That means a lot, thanks! That was my design goal with the page: figuring out the best way to get the idea across _without_ the user having to read a lot of text and stare at the wall until they got it.
I've been casting around for the next idea to do a visualization of, adding yours to the list.
(as for a partial answer your second question: the answer is going to be that Montgomery curves like Curve25519 have a method [Montgomery ladder] to quickly and timing-safely calculate only the x values of point multiplication. Faster _and_ more likely to be implemented securely than NIST curves, by design. Unfortunately I don't know the details of BrainPool, yet?)
Yes, Curve25519 is the curve itself (and associate params), Ed25519 is the signature system implemented on top of C25519, and X25519 is the ECDHE mechanism implemented on top of C25519. This page talks mostly about the C and a little of the X, and doesn't go into Ed.
If I may offer a critique: the final example with Alice and Bob went too fast. I watched it 5 times and I'm a bit lost. I'll rewatch it again later
- Alice computes A
- Bob computes B
- there’s a 3? second delay
- Alice and Bob simultaneously compute the shared secret by multiplying their private key by the others’ public key
For me, I think breaking it up after the Public Keys are generated would have helped.
I lost track the first time after the public keys are computed and exchanged. The exchange is what I think I missed.
Basically, you should not have several things changing in different places at the same time because human can only focus at one point. Maybe it would be better to add pauses in the sequence, animate one thing, wait a little, then animate other thing. Let the user stop and think a bit about what he/she have seen.
For example, in the image "Repeated addition of a point P" the points and lines are constantly moving, and I don't have time to look at the formula. I see that it is changing, but I cannot read it while looking at the animation. Maybe it would be better if the points stopped moving for a while, then the formula would change, then you give some time to read and comprehend it and then points continue moving.
Or maybe you could write all the formulas on the side, and have a box or selection moving over them. This way the viewer can see how the formulas are related to each other and doesn't have to remember previous ones.
Also, in the image "Point addition is associative and commutative" formulas seem to be random and do not illustrate anything. For example, I see 5P + P = 6P, then 2P + P = 3P, then 6P + P = 7P. So what it should mean?
Maybe a better way to illustrate these laws would be to have two images that produce the same result, for example P + 6P = 7P and 3P + 4P = 7P. It is easier to compare images side-by-side.
Instead of percent sign it might be better to use "mod" as percent sign is understood only by programmers but not by people familiar with mathematical notation.
To illustrate addition you might use a circle (or an ellipse, or even a square, why not) instead of a straight line. This way the wrapping behaviour would be more obvious. To illustrate multiplication, you could draw several sequential arcs (so that the multiplication is represented as several additions). And for negation, two arcs extending in the opposite direction from zero.
I don't understand how to illustrate inverse numbers though. Maybe several arcs that start at zero, end at 1 and number of them is the inverse value?
For the last illustration it definitely would help if it had some key points on the side, showing what we have done and what we are doing now.
PS: Great work, thank you! :)
I solve that problem by using Common Lisp. Because arbitrary bigints are built-in, that's a big chunk of the problem you don't need to worry about. You still need to write a Montgomery multiplier (because otherwise you'd fill available RAM or the divisions would slow everything to a crawl) but that's straightforward. Common Lisp makes exploring crypto algorithms easy.
I want to know HOW they work, especially in C, since that's what the majority of popular crypto libraries are written in.
The boring half is all carry-the-one manual operations that are very much like the addition, multi-digit multiplication, and long division that you learned at a classroom chalkboard.
The more interesting is things like modular exponentiation: there's a trick to computing n^e%p for large values, https://en.wikipedia.org/wiki/Modular_exponentiation goes into some detail. It's an operation used in both RSA and public curve cryptography.
I once emailed Grant from 3b1b and asked if he could explain convolution. Not neural-net convolution, but transfer convolution you learn in linear systems: e.g. f * g where you flip and slide g over f.
His short response: "That's too boring." I was a little miffed. Well, yeah, ECC is boring too, until someone like you makes cool graphics.
Anyway, thanks again!
Instead you'll need a fixed-size bigint lib with constant time guarantees.
Very nice page BTW. I've written C25519 code and I now understand my own code better because of your logical, step-by-step presentation.
x^21 = x^16 * x^4 * x
... = (((x^2)^2)^2)^2 * (x^2)^2 * x
Integer square roots can be done using binary search, which is O(n) for an n-bit number, but Newton's method can be used and it's usually much faster.Now, if the variety in question is a curve, the codimension 1 subvarieties will be of dimension 0, that is, finite sets of points. Moreover, if the curve is of degree 3, then hyperplanes (lines) will intersect it in exactly 3 points (counting the tangent intersections properly). Thus, we will get a bunch of constraints of the form:
P + Q + R = 0
This makes our huge group of linear combinations into rather simple group of points: take two points, P and Q. Run line across them, take third point of intersection: this is the negative of the sum P + Q. This is the procedure shown on the animations of the OP.
The point of this is that none of this is arbitrary: it’s just a lucky coincidence that happens only in dimension 1 and degree 3. One can introduce group structure on some other complex curves (which will actually look to us like surfaces), but it is not nearly as straightforward.
You might be interested in the fact that a variant of this visual representation still works: https://www.juricho.me/files/masterarbeit-hyperelliptic_curv...
Each point that you pick is going to have a different number of times it can be added to itself before it lands on a point that has the same x-value but different y-value, and then the "point addition" operation draws a vertical line and the point goes to infinity. The number of times you can add a point to itself before it happens and the cycle resets is called the point's "order".
Most of the points on the graph will repeat themselves after less than a dozen times. The one I picked repeats itself after 72 points, which is great because that's every point on the curve. I chose it by writing a little program that tried each point and returned the best one.
Compare that to a "real" curve like Curve25519: it has the base point at x=9 and can repeat itself over 2^252 times before repeating. The author of that curve used a different technique to find the point's order (obviously he didn't try adding the point to itself a trillion^6 times) but the idea's the same.
Many many thanks for this brilliantly depicted explanation!
Ot: I also looked up ulfheim after I realized your first name is Michael, not Ulf.
Unfortunately a few years ago a racist hate group also started using the name for their own purposes. Today I've started the process of moving all my hosts to a new domain name, xargs.org .
As an algebraic geometer, I have a minor correction: The graphic "examples of elliptic curves" features the singular curve y^2 = x^3. This is not an elliptic curves, because by definition elliptic curves are smooth.
I didn't think anyone would notice/care, but I'll tweak it to skip over that example.
You should mention the generic rule: P+(Q+R) = (P+Q)+R, even if it's much more tricky to show than P+(P+P)=(P+P)+P.
(pushed)
226 / 9
= (226*34) / (9*34)
= 7684 / 306
= 7684 / 1 (since 306 = 1 mod 61)
= 59 / 1 (since 7684 = 59 mod 61)
I think y3=2888/7 is a typo for 2888/27, which also equals 55 by a similar calculation (1/27 = 52 mod 61).https://gist.github.com/syncsynchalt/ed02e39ad7adc8580b1086f...
Looking at your comment the disconnect seems to be at the division step: when performing a division such as 226/9, look up or calculate the multiplicative inverse for 9 (you can use the table at https://curves.ulfheim.net/inverse61.html), which is 34, and multiply by that instead. This is explained at https://curves.ulfheim.net/#division-multiplicative-inverse
In F61, 226/9 = 226*34 = 7684 % 61 = 59.
In F61, 2888/27 = 2888*52 = 150176 % 61 = 55.
(you can also proactively reduce those numerators and calculate with some smaller numbers):
(226%61)/9 => 43/9
(2888%61)/27 => 21/27
so we can create an isomorphism(?) between the field (Z_61, +, *) and points on a modular elliptic curve with a base point P using function g:= g(k) = k * P
g(k) is fast to compute with the doubling method, but the inverse requires brute force. Even if you know k_a * P and k_b * P, computing k_a * k_b * P is hard.
However, if you know k_a or k_b (either private key) you can easily find k_a * g(k_b) = k_b * g(k_a) = k_a * k_b * P.
A monument of theoretical physics and mathematics!
The ladder procedure is spelled out in https://datatracker.ietf.org/doc/html/rfc7748, though you'll also need to provide your own constant-time conditional variable swap (they give the xor swap trick as an example).
Brilliantly done!