From fd179ede27809fe526a897d390887ccadd2c9168 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Tue, 2 Sep 2014 22:26:38 +0200
Subject: [PATCH] New function curve25519_eh_to_x.

---
 ChangeLog            | 10 ++++++
 Makefile.in          |  2 +-
 curve25519-eh-to-x.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
 curve25519-mul-g.c   |  2 +-
 curve25519-mul.c     |  2 +-
 ecc-internal.h       |  5 +++
 6 files changed, 99 insertions(+), 3 deletions(-)
 create mode 100644 curve25519-eh-to-x.c

diff --git a/ChangeLog b/ChangeLog
index 0f4b63bb..96175e2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-09-02  Niels Möller  <nisse@lysator.liu.se>
+
+	* curve25519-eh-to-x.c (curve25519_eh_to_x): New file, new
+	function. The curve25519 transform currently done by ecc_eh_to_a,
+	but which should eventually be eliminted from that function.
+	* Makefile.in (hogweed_SOURCES): Added curve25519-eh-to-x.c.
+	* ecc-internal.h (curve25519_eh_to_x): Declare it.
+	* curve25519-mul.c (curve25519_mul): Use it.
+	* curve25519-mul-g.c (curve25519_mul_g): Likewise.
+
 2014-08-29  Niels Möller  <nisse@lysator.liu.se>
 
 	* testsuite/testutils.c (test_ecc_mul_j): Renamed, to ...
diff --git a/Makefile.in b/Makefile.in
index 92ef8187..50fcfb4b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -174,7 +174,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
 		  ecc-point.c ecc-scalar.c ecc-point-mul.c ecc-point-mul-g.c \
 		  ecc-ecdsa-sign.c ecdsa-sign.c \
 		  ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c \
-		  curve25519-mul-g.c curve25519-mul.c \
+		  curve25519-mul-g.c curve25519-mul.c curve25519-eh-to-x.c \
 		  $(OPT_HOGWEED_SOURCES)
 
 HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
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
+}
diff --git a/curve25519-mul-g.c b/curve25519-mul-g.c
index a695dad0..0106ac7c 100644
--- a/curve25519-mul-g.c
+++ b/curve25519-mul-g.c
@@ -64,7 +64,7 @@ curve25519_mul_g (uint8_t *r, const uint8_t *n)
   mpn_set_base256_le (x, ecc_size, t, CURVE25519_SIZE);
 
   ecc_mul_g_eh (&nettle_curve25519, p, x, scratch_out);
-  ecc_eh_to_a (&nettle_curve25519, 1, x, p, scratch_out);
+  curve25519_eh_to_x (x, p, scratch_out);
 
   mpn_get_base256_le (r, CURVE25519_SIZE, x, ecc_size);
   gmp_free_limbs (scratch, itch);
diff --git a/curve25519-mul.c b/curve25519-mul.c
index e94e26b4..cc122bc0 100644
--- a/curve25519-mul.c
+++ b/curve25519-mul.c
@@ -82,7 +82,7 @@ curve25519_mul (uint8_t *q, const uint8_t *n, const uint8_t *p)
   mpn_set_base256_le (s, ecc->size, t, CURVE25519_SIZE);
   
   ecc_mul_a_eh (ecc, x, s, x, scratch_out);
-  ecc_eh_to_a (ecc, 1, s, x, scratch_out);
+  curve25519_eh_to_x (s, x, scratch_out);
   mpn_get_base256_le (q, CURVE25519_SIZE, s, ecc->size);
 
   gmp_free_limbs (scratch, itch);
diff --git a/ecc-internal.h b/ecc-internal.h
index 3da3f240..f6f0cd1e 100644
--- a/ecc-internal.h
+++ b/ecc-internal.h
@@ -64,6 +64,7 @@
 #define sec_tabselect _nettle_sec_tabselect
 #define sec_modinv _nettle_sec_modinv
 #define ecc_25519_sqrt _nettle_ecc_25519_sqrt
+#define curve25519_eh_to_x _nettle_curve25519_eh_to_x
 
 #define ECC_MAX_SIZE ((521 + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
 
@@ -266,6 +267,10 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n,
 int
 ecc_25519_sqrt(mp_limb_t *rp, const mp_limb_t *ap);
 
+void
+curve25519_eh_to_x (mp_limb_t *xp, const mp_limb_t *p,
+		    mp_limb_t *scratch);
+
 /* Current scratch needs: */
 #define ECC_MODINV_ITCH(size) (3*(size))
 #define ECC_J_TO_A_ITCH(size) (5*(size))
-- 
GitLab