|
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 |
}
|