mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch)
{
+#define x1 p
+#define y1 (p + ecc->p.size)
+#define z1 (p + 2*ecc->p.size)
+
+#define x2 r
+#define y2 (r + ecc->p.size)
+#define z2 (r + 2*ecc->p.size)
+
/* Formulas (from djb,
http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl):
y' = e*(c-d) mul e, j
z' = e*j mul
*/
-#define b scratch
-#define c (scratch + ecc->p.size)
-#define d (scratch + 2*ecc->p.size)
-#define e (scratch + 3*ecc->p.size)
-#define j (scratch + 4*ecc->p.size)
-
- /* b */
- ecc_mod_add (&ecc->p, e, p, p + ecc->p.size);
- ecc_mod_sqr (&ecc->p, b, e, b);
-
- /* c */
- ecc_mod_sqr (&ecc->p, c, p, c);
- /* d */
- ecc_mod_sqr (&ecc->p, d, p + ecc->p.size, d);
- /* h, can use r as scratch, even for in-place operation. */
- ecc_mod_sqr (&ecc->p, r, p + 2*ecc->p.size, r);
- /* e, */
- ecc_mod_add (&ecc->p, e, c, d);
- /* j */
- ecc_mod_add (&ecc->p, r, r, r);
- ecc_mod_sub (&ecc->p, j, e, r);
-
- /* x' */
- ecc_mod_sub (&ecc->p, b, b, e);
- ecc_mod_mul (&ecc->p, r, b, j, r);
- /* y' */
- ecc_mod_sub (&ecc->p, c, c, d); /* Redundant */
- ecc_mod_mul (&ecc->p, r + ecc->p.size, e, c, r + ecc->p.size);
- /* z' */
- ecc_mod_mul (&ecc->p, b, e, j, b);
- mpn_copyi (r + 2*ecc->p.size, b, ecc->p.size);
+#define C scratch
+#define D (scratch + 1*ecc->p.size)
+#define B (scratch + 2*ecc->p.size)
+
+#define E C
+
+ ecc_mod_sqr (&ecc->p, C, x1, C); /* C */
+ ecc_mod_sqr (&ecc->p, D, y1, D); /* C, D */
+ ecc_mod_add (&ecc->p, B, x1, y1);
+ ecc_mod_sqr (&ecc->p, B, B, x2); /* C, D, B */
+
+ /* c-d stored at y' */
+ ecc_mod_sub (&ecc->p, y2, C, D);
+ ecc_mod_add (&ecc->p, E, C, D); /* B, E */
+ /* b-e stored at x' */
+ ecc_mod_sub (&ecc->p, x2, B, E); /* E */
+
+ /* Use D as scratch for the following multiplies. */
+ ecc_mod_mul (&ecc->p, y2, y2, E, D);
+
+ /* h and j stored at z' */
+ ecc_mod_sqr (&ecc->p, z2, z1, D);
+ ecc_mod_add (&ecc->p, z2, z2, z2);
+ ecc_mod_sub (&ecc->p, z2, E, z2);
+ ecc_mod_mul (&ecc->p, x2, x2, z2, D);
+ ecc_mod_mul (&ecc->p, z2, z2, E, D);
}