2 * Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 3 of
9 * the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 /* Based on public domain code of LibTomCrypt by Tom St Denis.
22 * Adapted to gmp and nettle by Nikos Mavrogiannopoulos.
28 @file ecc_projective_dbl_point.c
29 ECC Crypto, Tom St Denis
32 #ifdef ECC_SECP_CURVES_ONLY
36 @param P The point to double
37 @param R [out] The destination of the double
38 @param modulus The modulus of the field the ECC curve is in
39 @param mp The "b" value from montgomery_setup()
43 ecc_projective_dbl_point (ecc_point
* P
, ecc_point
* R
, mpz_t a
/* a is -3 */,
49 if (P
== NULL
|| R
== NULL
|| modulus
== NULL
)
52 if ((err
= mp_init_multi(&t1
, &t2
, NULL
)) != 0) {
63 mpz_mul(t1
, R
->z
, R
->z
);
64 mpz_mod(t1
, t1
, modulus
);
66 mpz_mul(R
->z
, R
->y
, R
->z
);
67 mpz_mod(R
->z
, R
->z
, modulus
);
69 mpz_add(R
->z
, R
->z
, R
->z
);
70 if (mpz_cmp(R
->z
, modulus
) >= 0) {
71 mpz_sub(R
->z
, R
->z
, modulus
);
75 mpz_sub(t2
, R
->x
, t1
);
76 if (mpz_cmp_ui(t2
, 0) < 0) {
77 mpz_add(t2
, t2
, modulus
);
80 mpz_add(t1
, t1
, R
->x
);
81 if (mpz_cmp(t1
, modulus
) >= 0) {
82 mpz_sub(t1
, t1
, modulus
);
86 mpz_mod(t2
, t2
, modulus
);
89 if (mpz_cmp(t1
, modulus
) >= 0) {
90 mpz_sub(t1
, t1
, modulus
);
94 if (mpz_cmp(t1
, modulus
) >= 0) {
95 mpz_sub(t1
, t1
, modulus
);
99 mpz_add(R
->y
, R
->y
, R
->y
);
100 if (mpz_cmp(R
->y
, modulus
) >= 0) {
101 mpz_sub(R
->y
, R
->y
, modulus
);
104 mpz_mul(R
->y
, R
->y
, R
->y
);
105 mpz_mod(R
->y
, R
->y
, modulus
);
107 mpz_mul(t2
, R
->y
, R
->y
);
108 mpz_mod(t2
, t2
, modulus
);
111 mpz_add(t2
, t2
, modulus
);
113 mpz_divexact_ui(t2
, t2
, 2);
115 mpz_mul(R
->y
, R
->y
, R
->x
);
116 mpz_mod(R
->y
, R
->y
, modulus
);
119 mpz_mul(R
->x
, t1
, t1
);
120 mpz_mod(R
->x
, R
->x
, modulus
);
122 mpz_sub(R
->x
, R
->x
, R
->y
);
123 if (mpz_cmp_ui(R
->x
, 0) < 0) {
124 mpz_add(R
->x
, R
->x
, modulus
);
127 mpz_sub(R
->x
, R
->x
, R
->y
);
128 if (mpz_cmp_ui(R
->x
, 0) < 0) {
129 mpz_add(R
->x
, R
->x
, modulus
);
133 mpz_sub(R
->y
, R
->y
, R
->x
);
134 if (mpz_cmp_ui(R
->y
, 0) < 0) {
135 mpz_add(R
->y
, R
->y
, modulus
);
138 mpz_mul(R
->y
, R
->y
, t1
);
139 mpz_mod(R
->y
, R
->y
, modulus
);
141 mpz_sub(R
->y
, R
->y
, t2
);
142 if (mpz_cmp_ui(R
->y
, 0) < 0) {
143 mpz_add( R
->y
, R
->y
, modulus
);
148 mp_clear_multi(&t1
, &t2
, NULL
);
152 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_projective_dbl_point.c,v $ */
153 /* $Revision: 1.11 $ */
154 /* $Date: 2007/05/12 14:32:35 $ */