diff options
author | Niels Möller <nisse@lysator.liu.se> | 2013-02-15 11:01:13 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2013-02-15 11:01:13 +0100 |
commit | 3e33071e4a7070aae5a6017cc9b37dada064a531 (patch) | |
tree | f676f4670d82ad9dcc61fe94d23a7eee070b1773 /ecc-j-to-a.c | |
parent | a3dd891c7673f787e73aa19ae3ac99f25349c20e (diff) | |
download | nettle-3e33071e4a7070aae5a6017cc9b37dada064a531.tar.gz |
Integrate ecc_mul_g.
Diffstat (limited to 'ecc-j-to-a.c')
-rw-r--r-- | ecc-j-to-a.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/ecc-j-to-a.c b/ecc-j-to-a.c new file mode 100644 index 00000000..ae56bbaf --- /dev/null +++ b/ecc-j-to-a.c @@ -0,0 +1,115 @@ +/* ecc-j-to-a.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" + +mp_size_t +ecc_j_to_a_itch (const struct ecc_curve *ecc) +{ + /* Needs 2*ecc->size + scratch for ecc_modq_inv */ + return ECC_J_TO_A_ITCH (ecc->size); +} + +void +ecc_j_to_a (const struct ecc_curve *ecc, + int flags, + mp_limb_t *r, const mp_limb_t *p, + mp_limb_t *scratch) +{ +#define izp scratch +#define up (scratch + ecc->size) +#define iz2p (scratch + ecc->size) +#define iz3p (scratch + 2*ecc->size) +#define tp scratch + + mp_limb_t cy; + + if (ecc->use_redc) + { + /* Set v = (r_z / B^2)^-1, + + r_x = p_x v^2 / B^3 = ((v/B * v)/B * p_x)/B + r_y = p_y v^3 / B^4 = (((v/B * v)/B * v)/B * p_x)/B + + Skip the first redc, if we want to stay in Montgomery + representation. + */ + + mpn_copyi (up, p + 2*ecc->size, ecc->size); + mpn_zero (up + ecc->size, ecc->size); + ecc->redc (ecc, up); + mpn_zero (up + ecc->size, ecc->size); + ecc->redc (ecc, up); + + ecc_modp_inv (ecc, izp, up, up + ecc->size); + + if (flags & 1) + { + /* Divide this common factor by B */ + mpn_copyi (iz3p, izp, ecc->size); + mpn_zero (iz3p + ecc->size, ecc->size); + ecc->redc (ecc, iz3p); + + ecc_modp_mul (ecc, iz2p, izp, iz3p); + } + else + ecc_modp_sqr (ecc, iz2p, izp); + } + else + { + /* Set s = p_z^{-1}, r_x = p_x s^2, r_y = p_y s^3 */ + + mpn_copyi (up, p+2*ecc->size, ecc->size); /* p_z */ + ecc_modp_inv (ecc, izp, up, up + ecc->size); + + ecc_modp_sqr (ecc, iz2p, izp); + } + + ecc_modp_mul (ecc, iz3p, iz2p, p); + /* ecc_modp (and ecc_modp_mul) may return a value up to 2p - 1, so + do a conditional subtraction. */ + cy = mpn_sub_n (r, iz3p, ecc->p, ecc->size); + cnd_copy (cy, r, iz3p, ecc->size); + + if (flags & 2) + /* Skip y coordinate */ + return; + + ecc_modp_mul (ecc, iz3p, iz2p, izp); + ecc_modp_mul (ecc, tp, iz3p, p + ecc->size); + /* And a similar subtraction. */ + cy = mpn_sub_n (r + ecc->size, tp, ecc->p, ecc->size); + cnd_copy (cy, r + ecc->size, tp, ecc->size); + +#undef izp +#undef up +#undef iz2p +#undef iz3p +#undef tp +} |