I have some misunderstanding about EdDSA conversion coordinates between Montgomery curve and twisted Edwards curve. In https://www.rfc-editor.org/rfc/rfc7748 I see that a base point for Curve25519 is

Montgomery curve:

U(P)  9
V(P)  14781619447589544791020593568409986887264606134616475288964881837755586237401

Twisted Edwards curve:

X(P)  15112221349535400772501151409588531511454012693041857206046113283949847762202
Y(P)  46316835694926478169428394003475163141307993866256225615783033603165251855960

and then I see

The birational maps are:

$(u, v) = \frac{1+y}{1-y}, \sqrt{-486664}*\frac{u}{x}$

$(x, y) = \sqrt{-486664}*\frac{u}{v}, \frac{u-1}{u+1}$

But if we try convert $(x,y)$ to $(u,v)$ or $(u,v)$ to $(x,y)$ by using these formulas, we will not get correct answers. For example convert y-coordinate to u-coordinate:


result will not be equal to


How can I convert coordinates between Montgomery curve and twisted Edwards curve correctly?


3 Answers 3


The formulas actually work. You just have to keep in mind to make computation in the field of intergers modulo $2^{255}-19$ and that there are actually two square roots, you need to use the right one if you want to have the expected result.

You can test the following SAGE code

X_P = gf(15112221349535400772501151409588531511454012693041857206046113283949847762202)
Y_P = gf(46316835694926478169428394003475163141307993866256225615783033603165251855960)
u = (1+Y_P)/(1-Y_P) 
v = gf(-486664).sqrt()*u/X_P,-(gf(-486664).sqrt())*u/X_P
print u
print v

on the Sage Cell server.


You operations have to be modulo $p$ where $p=2^{255}-19$ because you are working in $\mathbb{F}_p$.


Note you're doing direct division instead of modular inverse.

Since there is no division in elliptic curve arithmetic, you need to do mod inverse. pow function could be used as a helper here; it takes third argument as modulus:

>>> P = 2 ** 255 - 19
>>> X = 15112221349535400772501151409588531511454012693041857206046113283949847762202
>>> Y = 46316835694926478169428394003475163141307993866256225615783033603165251855960
>>> mod_inverse = lambda x: pow(x, P - 2, P)
>>> # we are replacing `/ 1 - Y` with `* inverse(1 - Y)`
>>> ((1 + Y) * mod_inverse(1 - Y)) % P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.