summaryrefslogtreecommitdiff
path: root/ecc-add-jja.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2013-02-15 11:01:13 +0100
committerNiels Möller <nisse@lysator.liu.se>2013-02-15 11:01:13 +0100
commit3e33071e4a7070aae5a6017cc9b37dada064a531 (patch)
treef676f4670d82ad9dcc61fe94d23a7eee070b1773 /ecc-add-jja.c
parenta3dd891c7673f787e73aa19ae3ac99f25349c20e (diff)
downloadnettle-3e33071e4a7070aae5a6017cc9b37dada064a531.tar.gz
Integrate ecc_mul_g.
Diffstat (limited to 'ecc-add-jja.c')
-rw-r--r--ecc-add-jja.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/ecc-add-jja.c b/ecc-add-jja.c
new file mode 100644
index 00000000..f358e8ba
--- /dev/null
+++ b/ecc-add-jja.c
@@ -0,0 +1,122 @@
+/* ecc-dup-jj.c */
+
+/* nettle, low-level cryptographics library
+ *
+ * Copyright (C) 2013 Niels Möller
+ *
+ * The nettle library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The nettle library 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 Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the nettle library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+/* Development of Nettle's ECC support was funded by Internetfonden. */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "ecc.h"
+#include "ecc-internal.h"
+
+/* NOTE: Behaviour for corner cases:
+
+ + p = 0 ==> r = 0 (invalid except if also q = 0)
+
+ + q = 0 ==> r = invalid
+
+ + p = -q ==> r = 0, correct!
+
+ + p = q ==> r = 0, invalid
+*/
+
+mp_size_t
+ecc_add_jja_itch (const struct ecc_curve *ecc)
+{
+ return ECC_ADD_JJA_ITCH (ecc->size);
+}
+
+void
+ecc_add_jja (const struct ecc_curve *ecc,
+ mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q,
+ mp_limb_t *scratch)
+{
+ /* Formulas, from djb,
+ http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b):
+
+ Computation Operation Live variables
+
+ ZZ = Z_1^2 sqr ZZ
+ H = X_2*ZZ - X_1 mul (djb: U_2) ZZ, H
+ HH = H^2 sqr ZZ, H, HH
+ ZZZ = ZZ*Z_1 mul ZZ, H, HH, ZZZ
+ Z_3 = (Z_1+H)^2-ZZ-HH sqr H, HH, ZZZ
+ W = 2 (Y_2*ZZZ - Y_1) mul (djb: S_2) H, HH, W
+ I = 4*HH H, W, I
+ J = H*I mul W, I, J
+ V = X_1*I mul W, J, V
+ X_3 = W^2-J-2*V sqr W, J, V
+ Y_3 = W*(V-X_3)-2*Y_1*J mul, mul
+ */
+#define zz scratch
+#define h (scratch + ecc->size)
+#define hh (scratch + 2*ecc->size)
+#define w (scratch + 3*ecc->size)
+#define j (scratch + 4*ecc->size)
+#define v scratch
+
+#define x1 p
+#define y1 (p + ecc->size)
+#define z1 (p + 2*ecc->size)
+#define x2 q
+#define y2 (q + ecc->size)
+
+ /* zz */
+ ecc_modp_sqr (ecc, zz, z1);
+ /* h*/
+ ecc_modp_mul (ecc, h, x2, zz);
+ ecc_modp_sub (ecc, h, h, x1);
+ /* hh */
+ ecc_modp_sqr (ecc, hh, h);
+ /* Do z^3 early, store at w. */
+ ecc_modp_mul (ecc, w, zz, z1);
+ /* z_3, use j area for scratch */
+ ecc_modp_add (ecc, r + 2*ecc->size, p + 2*ecc->size, h);
+ ecc_modp_sqr (ecc, j, r + 2*ecc->size);
+ ecc_modp_sub (ecc, j, j, zz);
+ ecc_modp_sub (ecc, r + 2*ecc->size, j, hh);
+
+ /* w */
+ ecc_modp_mul (ecc, j, y2, w);
+ ecc_modp_sub (ecc, w, j, y1);
+ ecc_modp_mul_1 (ecc, w, w, 2);
+
+ /* i replaces hh, j */
+ ecc_modp_mul_1 (ecc, hh, hh, 4);
+ ecc_modp_mul (ecc, j, hh, h);
+
+ /* v */
+ ecc_modp_mul (ecc, v, x1, hh);
+
+ /* x_3, use (h, hh) as sqratch */
+ ecc_modp_sqr (ecc, h, w);
+ ecc_modp_sub (ecc, r, h, j);
+ ecc_modp_submul_1 (ecc, r, v, 2);
+
+ /* y_3, use (h, hh) as sqratch */
+ ecc_modp_mul (ecc, h, y1, j); /* frees j */
+ ecc_modp_sub (ecc, r + ecc->size, v, r);
+ ecc_modp_mul (ecc, j, r + ecc->size, w);
+ ecc_modp_submul_1 (ecc, j, h, 2);
+ mpn_copyi (r + ecc->size, j, ecc->size);
+}