Blame lib/nettle/ecc/ecc-dup-jj.c

Packit Service 991b93
/* ecc-dup-jj.c
Packit Service 991b93
Packit Service 991b93
   Copyright (C) 2013 Niels Möller
Packit Service 991b93
Packit Service 991b93
   This file is part of GNU Nettle.
Packit Service 991b93
Packit Service 991b93
   GNU Nettle is free software: you can redistribute it and/or
Packit Service 991b93
   modify it under the terms of either:
Packit Service 991b93
Packit Service 991b93
     * the GNU Lesser General Public License as published by the Free
Packit Service 991b93
       Software Foundation; either version 3 of the License, or (at your
Packit Service 991b93
       option) any later version.
Packit Service 991b93
Packit Service 991b93
   or
Packit Service 991b93
Packit Service 991b93
     * the GNU General Public License as published by the Free
Packit Service 991b93
       Software Foundation; either version 2 of the License, or (at your
Packit Service 991b93
       option) any later version.
Packit Service 991b93
Packit Service 991b93
   or both in parallel, as here.
Packit Service 991b93
Packit Service 991b93
   GNU Nettle is distributed in the hope that it will be useful,
Packit Service 991b93
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 991b93
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 991b93
   General Public License for more details.
Packit Service 991b93
Packit Service 991b93
   You should have received copies of the GNU General Public License and
Packit Service 991b93
   the GNU Lesser General Public License along with this program.  If
Packit Service 991b93
   not, see http://www.gnu.org/licenses/.
Packit Service 991b93
*/
Packit Service 991b93
Packit Service 991b93
/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
Packit Service 991b93
Packit Service 991b93
#if HAVE_CONFIG_H
Packit Service 991b93
# include "config.h"
Packit Service 991b93
#endif
Packit Service 991b93
Packit Service 991b93
#include <nettle/ecc.h>
Packit Service 991b93
#include "ecc-internal.h"
Packit Service 991b93
Packit Service 991b93
/* NOTE: Behaviour for corner cases:
Packit Service 991b93
Packit Service 991b93
   + p = 0  ==>  r = 0, correct!
Packit Service 991b93
*/
Packit Service 991b93
void
Packit Service 991b93
ecc_dup_jj (const struct ecc_curve *ecc,
Packit Service 991b93
	    mp_limb_t *r, const mp_limb_t *p,
Packit Service 991b93
	    mp_limb_t *scratch)
Packit Service 991b93
{
Packit Service 991b93
  /* Formulas (from djb,
Packit Service 991b93
     http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b):
Packit Service 991b93
Packit Service 991b93
     Computation			Operation	Live variables
Packit Service 991b93
     delta = z^2			sqr		delta
Packit Service 991b93
     gamma = y^2			sqr		delta, gamma
Packit Service 991b93
     z' = (y+z)^2-gamma-delta		sqr		delta, gamma
Packit Service 991b93
     alpha = 3*(x-delta)*(x+delta)	mul		gamma, beta, alpha
Packit Service 991b93
     beta = x*gamma			mul		gamma, beta, alpha
Packit Service 991b93
     x' = alpha^2-8*beta		sqr		gamma, beta, alpha
Packit Service 991b93
     y' = alpha*(4*beta-x')-8*gamma^2	mul, sqr
Packit Service 991b93
  */
Packit Service 991b93
Packit Service 991b93
#define delta  scratch
Packit Service 991b93
#define gamma (scratch + ecc->p.size)
Packit Service 991b93
#define beta  (scratch + 2*ecc->p.size)
Packit Service 991b93
#define g2    (scratch + 3*ecc->p.size)
Packit Service 991b93
#define sum   (scratch + 4*ecc->p.size)
Packit Service 991b93
#define alpha  scratch /* Overlap delta */
Packit Service 991b93
  
Packit Service 991b93
#define xp p
Packit Service 991b93
#define yp (p + ecc->p.size)
Packit Service 991b93
#define zp (p + 2*ecc->p.size)
Packit Service 991b93
  
Packit Service 991b93
  /* delta */
Packit Service 991b93
  ecc_mod_sqr (&ecc->p, delta, zp);
Packit Service 991b93
Packit Service 991b93
  /* gamma */
Packit Service 991b93
  ecc_mod_sqr (&ecc->p, gamma, yp);
Packit Service 991b93
Packit Service 991b93
  /* z'. Can use beta area as scratch. */
Packit Service 991b93
  ecc_mod_add (&ecc->p, r + 2*ecc->p.size, yp, zp);
Packit Service 991b93
  ecc_mod_sqr (&ecc->p, beta, r + 2*ecc->p.size);
Packit Service 991b93
  ecc_mod_sub (&ecc->p, beta, beta, gamma);
Packit Service 991b93
  ecc_mod_sub (&ecc->p, r + 2*ecc->p.size, beta, delta);
Packit Service 991b93
  
Packit Service 991b93
  /* alpha. Can use beta area as scratch, and overwrite delta. */
Packit Service 991b93
  ecc_mod_add (&ecc->p, sum, xp, delta);
Packit Service 991b93
  ecc_mod_sub (&ecc->p, delta, xp, delta);
Packit Service 991b93
  ecc_mod_mul (&ecc->p, beta, sum, delta);
Packit Service 991b93
  ecc_mod_mul_1 (&ecc->p, alpha, beta, 3);
Packit Service 991b93
Packit Service 991b93
  /* beta */
Packit Service 991b93
  ecc_mod_mul (&ecc->p, beta, xp, gamma);
Packit Service 991b93
Packit Service 991b93
  /* Do gamma^2 and 4*beta early, to get them out of the way. We can
Packit Service 991b93
     then use the old area at gamma as scratch. */
Packit Service 991b93
  ecc_mod_sqr (&ecc->p, g2, gamma);
Packit Service 991b93
  ecc_mod_mul_1 (&ecc->p, sum, beta, 4);
Packit Service 991b93
  
Packit Service 991b93
  /* x' */
Packit Service 991b93
  ecc_mod_sqr (&ecc->p, gamma, alpha);   /* Overwrites gamma and beta */
Packit Service 991b93
  ecc_mod_submul_1 (&ecc->p, gamma, sum, 2);
Packit Service 991b93
  mpn_copyi (r, gamma, ecc->p.size);
Packit Service 991b93
Packit Service 991b93
  /* y' */
Packit Service 991b93
  ecc_mod_sub (&ecc->p, sum, sum, r);
Packit Service 991b93
  ecc_mod_mul (&ecc->p, gamma, sum, alpha);
Packit Service 991b93
  ecc_mod_submul_1 (&ecc->p, gamma, g2, 8);
Packit Service 991b93
  mpn_copyi (r + ecc->p.size, gamma, ecc->p.size);
Packit Service 991b93
}