summaryrefslogtreecommitdiff
path: root/curve25519-eh-to-x.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2014-09-02 22:26:38 +0200
committerNiels Möller <nisse@lysator.liu.se>2014-09-02 22:26:38 +0200
commitfd179ede27809fe526a897d390887ccadd2c9168 (patch)
tree8735506d5d93beeedf604103fd1ba2ad667fcf53 /curve25519-eh-to-x.c
parent2e24e947de21d0c27db8b67bcf80911a3891ae2e (diff)
downloadnettle-fd179ede27809fe526a897d390887ccadd2c9168.tar.gz
New function curve25519_eh_to_x.
Diffstat (limited to 'curve25519-eh-to-x.c')
-rw-r--r--curve25519-eh-to-x.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/curve25519-eh-to-x.c b/curve25519-eh-to-x.c
new file mode 100644
index 00000000..14dcc4e8
--- /dev/null
+++ b/curve25519-eh-to-x.c
@@ -0,0 +1,81 @@
+/* curve25519-x.c
+
+ Copyright (C) 2014 Niels Möller
+
+ This file is part of GNU Nettle.
+
+ GNU Nettle is free software: you can redistribute it and/or
+ modify it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your
+ option) any later version.
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ or both in parallel, as here.
+
+ GNU Nettle is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+
+#include "curve25519.h"
+
+#include "ecc.h"
+#include "ecc-internal.h"
+
+/* Transform a point on the twisted Edwards curve to the curve25519
+ Montgomery curve, and return the x coordinate. */
+void
+curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p,
+ mp_limb_t *scratch)
+{
+#define vp (p + ecc->size)
+#define wp (p + 2*ecc->size)
+#define t0 scratch
+#define t1 (scratch + ecc->size)
+#define t2 (scratch + 2*ecc->size)
+
+ const struct ecc_curve *ecc = &nettle_curve25519;
+ mp_limb_t cy;
+
+ /* If u = U/W and v = V/W are the coordiantes of the point on the
+ Edwards curve we get the curve25519 x coordinate as
+
+ x = (1+v) / (1-v) = (W + V) / (W - V)
+ */
+ /* NOTE: For the infinity point, this subtraction gives zero (mod
+ p), which isn't invertible. For curve25519, the desired output is
+ x = 0, and we should be fine, since ecc_modp_inv returns 0
+ in this case. */
+ ecc_modp_sub (ecc, t0, wp, vp);
+ /* Needs 3*size scratch, for a total of 5*size */
+ ecc_modp_inv (ecc, t1, t0, t2);
+
+ ecc_modp_add (ecc, t0, wp, vp);
+ ecc_modp_mul (ecc, t2, t0, t1);
+
+ cy = mpn_sub_n (xp, t2, ecc->p, ecc->size);
+ cnd_copy (cy, xp, t2, ecc->size);
+#undef vp
+#undef wp
+#undef t0
+#undef t1
+#undef t2
+}