Score:2

Implementing Elliptic curve point addition and multiplication in Python

wf flag

I am learning Elliptic Curve cryptography, I have been working on an example from a book: example of problem with a=2,b=2, P=(5,1) and finding 2P

I don't fully understand the line where the slope is calculated, specifically how 2^(-1) * 9= 13 mod 17? I saw a post here that says to get the inverse with the Extended Euclidean algorithm.

I just don't see what 2^(-1) is the inverse for. What I understand from the EEA is that for gcd(n, a) = (sn + ta) = 1 mod n, then t is our inverse for a. So if the EEA is really the answer to find my answer, what values do I use in the algorithm, and why? Or is there something that I am doing wrong in Python? (I am not as experienced in Python)

My code is in Python 3.11.1, here:

import math

def add(P, Q, a, p):
    if P != Q:
        S = ((Q[1] - P[1])/(Q[0] - P[0])) % p
    else:
        S = ((3 * P[0] ** 2 + a)/ 2 * P[1]) % p

    print("S is: "+ str(S))

    x = (pow(S, 2) - P[0] - Q[0]) % p
    y = (S*(P[0] - x)- P[1]) % p

    return [x, y]

def main():
    P = [5,1]
    R = add(P, P, 2, 17)
    print("R is: "+ str(R))

if __name__ == '__main__':
    main()

and my output is

S is: 4.5
R is: [10.25, 9.375]

My expected output from the example is:

S is: 13
R is [6, 3]
poncho avatar
my flag
"I just don't see what 2^(-1) is the inverse for"; 2^(-1) is that number when, multiplied by 2 (modulo 17), results in 1.
Lachlan avatar
wf flag
@poncho How could I find that quickly? I don't fully see how we can use the EEA to find this.
Lachlan avatar
wf flag
@poncho Nevermind I see now, I did gcd(17,2) = 1*17+(-8)*2 and -8 mod 17 is 9 which is what we were looking for, this is correct right or is this a coincidence? Thanks for the help btw!
poncho avatar
my flag
That's right. IIRC, there are some built-ins in python that will do the work for you; one is pow(2, 17-2, 17) (which works because 17 is prime). More generally, the inverse of x modulo a prime p is pow(x, p-2, p)
Lachlan avatar
wf flag
@poncho Oh thanks, that makes things easier!
Score:3
ng flag

When there is $\displaystyle s=\frac{3{x_1}^2-1}{2y_1}$ in the context of Elliptic Curve, that's computed in a field, that is a set with addition and multiplication such that usual rules of algebra apply, including a well-defined division by anything except $0$.

When further that's in the context of cryptography, the field is a finite field, noted $\mathbb F_q$, that has $q\ge2$ elements. Often, and in the context of the question and the rest of this answer, $q$ is a prime $p$, and then $\mathbb F_p$ is simply the integers modulo $p$, under addition and multiplication modulo $p$. When with $x,y,z\in\mathbb F_p$ we write some equality like $x=y\,z$, that really means this equality stands modulo $p$, that is $x\equiv y\,z\pmod p$, which by definition means: $p$ divides $y\,z-x$, where $x,y,z\in\mathbb Z$.

For example, with $p=17$ as in the question, $10\cdot4\equiv6\pmod p$ because $p=17$ divides $10\cdot4-6=34$, thus when the context stipulates we are computing in $\mathbb F_p$ (which I assume in the following) it holds $10\cdot4=6$.

Division works just the same as in any field like the familiar reals $\mathbb R$ or $\mathbb C$: the notation $\displaystyle z=\frac xy$ by definition means $y\ne0$ and $x=y\,z$. If follows $\displaystyle10=\frac 64$.

To make the calculation $\displaystyle z\gets\frac xy$, the first step is to check that $y\ne0$ (remember that's modulo $p$). Then for very small numbers like in the question, it's entirely feasible to search for $z$ until $x=y\,z$. It's also possible, and more common, to first compute $\displaystyle\frac 1y$, also noted $y^{-1}$, then compute $z\gets y^{-1}\,x$.

To compute $y^{-1}$ from $y\ne0$

  • The textbook method is the Extended Euclidean Algorithm. Considering $y$ as an integer, we find integers $u$ and $v$ satisfying the Bezout equality $u\,p+v\,y=1$. It follows $v\bmod p$ is the desired $y^{-1}$. Since we do not need $u$, we need not compute it, and can use this. There are variants that work with non-negative integers at all steps, and others that need no modular reduction.
  • Since $p$ is prime, by Fermat's little theorem, it holds $y^{p-1}=1$, thus $y^{-1}=y^{p-2}$. This tends to be slower, though.

It's pedagogically useful to implement the EEA, in particular because it works in any finite ring. However Python's pow has been extended so that pow(y, -1, p) can be used to compute the modular inverse of y modulo p with many Python 3.8 and later. With even more versions, we can get away with pow(y, p-2, p).

The question's ((3 * P[0] ** 2 + a)/ 2 * P[1]) % p has two issues:

  • Most importantly, / is used for division, when that's the operator for (an approximation of) the division in $\mathbb R$, yielding a floating point value. Operator // would at least yield an integer, but when there's a rounding that would not be the correct result.
  • As an aside, precedence of operators is such that * P[1] is evaluated after and on the result of / 2, thus if that was not for the earlier issue, it would be computed $\displaystyle\frac{3{x_1}^2-1}2\,y_1$ rather than the desired $\displaystyle\frac{3{x_1}^2-1}{2y_1}$.

A correct expression is (3 * pow(P[0], 2, p) + a) * pow(2 * P[1], -1, p) % p. The first pow is to compute the square with reduction modulo $p$ (this is strictly optional). The second pow is to compute the modular inverse of the denominator.

There are other functional issues with the code, including the other computation of the slope and missing some cases; see the full addition algorithm in sec1 §3.2.2.

Lachlan avatar
wf flag
Thanks for the detailed answer, I realized later that I should have known this from the ElGamal Encryption. But it's good to know now so thanks for explaining the math behind it to me!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.