summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2014-07-14 21:50:53 +0200
committerNiels Möller <nisse@lysator.liu.se>2014-07-14 21:50:53 +0200
commita79c2ac58f582bf6e3a07a001c8c65baff47d123 (patch)
tree33b3e1de31908c26984e93b3c73fac82a1a1cb55
parent47dffbfb848552f2eb4de559aa5bbc5b657afc15 (diff)
downloadnettle-a79c2ac58f582bf6e3a07a001c8c65baff47d123.tar.gz
Implemented point addition for Edwards curves.
-rw-r--r--ChangeLog8
-rw-r--r--Makefile.in2
-rw-r--r--ecc-25519.c2
-rw-r--r--ecc-add-ehh.c114
-rw-r--r--ecc-internal.h1
-rw-r--r--ecc.h9
6 files changed, 134 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 03e7dd50..25474c48 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2014-07-14 Niels Möller <nisse@lysator.liu.se>
+ * ecc-add-ehh.c (ecc_add_ehh, ecc_add_ehh_itch): New file, new
+ functions.
+ * ecc.h (ecc_add_ehh, ecc_add_ehh_itch): Declare them.
+ * ecc-internal.h (ECC_ADD_EHH_ITCH): New macro.
+ * Makefile.in (hogweed_SOURCES): Added ecc-add-ehh.c.
+
+ * ecc-25519.c (nettle_curve25519): Use ecc_d instead of ecc_b.
+
* eccdata.c: For curve25519, output the Edwards curve constant,
ecc_d = (121665/121666) mod p.
diff --git a/Makefile.in b/Makefile.in
index 0c74f878..6831cc4a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -167,7 +167,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
ecc-25519.c \
ecc-size.c ecc-j-to-a.c ecc-a-to-j.c \
ecc-dup-jj.c ecc-add-jja.c ecc-add-jjj.c \
- ecc-dup-eh.c ecc-eh-to-a.c \
+ ecc-dup-eh.c ecc-add-ehh.c ecc-eh-to-a.c \
ecc-mul-g.c ecc-mul-a.c ecc-hash.c ecc-random.c \
ecc-point.c ecc-scalar.c ecc-point-mul.c ecc-point-mul-g.c \
ecc-ecdsa-sign.c ecdsa-sign.c \
diff --git a/ecc-25519.c b/ecc-25519.c
index 51414a30..806dfd98 100644
--- a/ecc-25519.c
+++ b/ecc-25519.c
@@ -75,7 +75,7 @@ const struct ecc_curve nettle_curve25519 =
ECC_PIPPENGER_K,
ECC_PIPPENGER_C,
ecc_p,
- ecc_b,
+ ecc_d, /* Use the Edwards curve constant. */
ecc_q,
ecc_g,
ecc_redc_g,
diff --git a/ecc-add-ehh.c b/ecc-add-ehh.c
new file mode 100644
index 00000000..140a6d7c
--- /dev/null
+++ b/ecc-add-ehh.c
@@ -0,0 +1,114 @@
+/* ecc-add-ehh.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 "ecc.h"
+#include "ecc-internal.h"
+
+mp_size_t
+ecc_add_ehh_itch (const struct ecc_curve *ecc)
+{
+ return ECC_ADD_EHH_ITCH (ecc->size);
+}
+
+/* Add two points on an Edwards curve, in homogeneous coordinates */
+void
+ecc_add_ehh (const struct ecc_curve *ecc,
+ mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q,
+ mp_limb_t *scratch)
+{
+#define x1 p
+#define y1 (p + ecc->size)
+#define z1 (p + 2*ecc->size)
+
+#define x2 q
+#define y2 (q + ecc->size)
+#define z2 (q + 2*ecc->size)
+
+#define x3 r
+#define y3 (r + ecc->size)
+#define z3 (r + 2*ecc->size)
+
+ /* Formulas (from djb,
+ http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl):
+
+ Computation Operation Live variables
+
+ A = z1*z2 mul A
+ B = A^2 sqr A, B
+ C = x1*x2 mul A, B, C
+ D = y1*y2 mul A, B, C, D
+ E = b*C*D 2 mul A, B, C, D, E
+ F = B - E A, B, C, D, E, F
+ G = B + E A, C, D, F, G
+ x3 = a*f*[(x1+y1)(x2+y2) - c - d] 3 mul A, C, D, G
+ y3 = a*g*(d-c) 2 mul F, G
+ z3 = f*g mul
+ */
+#define A scratch
+#define B (scratch + ecc->size)
+#define C (scratch + 2*ecc->size)
+#define D (scratch + 3*ecc->size)
+#define E (scratch + 4*ecc->size)
+#define F (scratch + 5*ecc->size)
+#define G (scratch + 6*ecc->size)
+#define T (scratch + 7*ecc->size)
+
+ ecc_modp_mul (ecc, A, z1, z2);
+ ecc_modp_sqr (ecc, B, A);
+ ecc_modp_mul (ecc, C, x1, x2);
+ ecc_modp_mul (ecc, D, y1, y2);
+ ecc_modp_mul (ecc, T, C, D);
+ ecc_modp_mul (ecc, E, T, ecc->b);
+ ecc_modp_sub (ecc, F, B, E);
+ ecc_modp_add (ecc, G, B, E);
+
+ /* x3 */
+ ecc_modp_add (ecc, B, x1, y1);
+ ecc_modp_add (ecc, E, x2, y2);
+ ecc_modp_mul (ecc, T, B, E);
+ ecc_modp_sub (ecc, T, T, C);
+ ecc_modp_sub (ecc, x3, T, D);
+ ecc_modp_mul (ecc, T, x3, A);
+ ecc_modp_mul (ecc, x3, T, F);
+
+ /* y3 */
+ ecc_modp_sub (ecc, C, D, C);
+ ecc_modp_mul (ecc, T, A, C);
+ ecc_modp_mul (ecc, y3, T, G);
+
+ /* z3 */
+ ecc_modp_mul (ecc, T, F, G);
+ mpn_copyi (z3, T, ecc->size);
+}
diff --git a/ecc-internal.h b/ecc-internal.h
index b91e343e..1fefd138 100644
--- a/ecc-internal.h
+++ b/ecc-internal.h
@@ -242,6 +242,7 @@ sec_modinv (mp_limb_t *vp, mp_limb_t *ap, mp_size_t n,
#define ECC_DUP_EH_ITCH(size) (5*(size))
#define ECC_ADD_JJA_ITCH(size) (6*(size))
#define ECC_ADD_JJJ_ITCH(size) (8*(size))
+#define ECC_ADD_EHH_ITCH(size) (9*(size))
#define ECC_MUL_G_ITCH(size) (9*(size))
#if ECC_MUL_A_WBITS == 0
#define ECC_MUL_A_ITCH(size) (12*(size))
diff --git a/ecc.h b/ecc.h
index 03129348..f8cadf5e 100644
--- a/ecc.h
+++ b/ecc.h
@@ -71,6 +71,8 @@ extern "C" {
#define ecc_add_jjj nettle_ecc_add_jjj
#define ecc_dup_eh_itch nettle_ecc_dup_eh_itch
#define ecc_dup_eh nettle_ecc_dup_eh
+#define ecc_add_ehh_itch nettle_ecc_add_ehh_itch
+#define ecc_add_ehh nettle_ecc_add_ehh
#define ecc_mul_g_itch nettle_ecc_mul_g_itch
#define ecc_mul_g nettle_ecc_mul_g
#define ecc_mul_a_itch nettle_ecc_mul_a_itch
@@ -243,6 +245,13 @@ ecc_dup_eh (const struct ecc_curve *ecc,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch);
+mp_size_t
+ecc_add_ehh_itch (const struct ecc_curve *ecc);
+void
+ecc_add_ehh (const struct ecc_curve *ecc,
+ mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q,
+ mp_limb_t *scratch);
+
/* Computes N * the group generator. N is an array of ecc_size()
limbs. It must be in the range 0 < N < group order, then R != 0,
and the algorithm can work without any intermediate values getting