documented update
[gnutls.git] / lib / nettle / ecc_mulmod_timing.c
bloba6b053dc43d732b85db8ab0bfd3184388a7c7d39
1 /*
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.
25 #include "ecc.h"
28 @file ecc_mulmod_timing.c
29 ECC Crypto, Tom St Denis
33 Perform a point multiplication (timing resistant)
34 @param k The scalar to multiply by
35 @param G The base point
36 @param R [out] Destination for kG
37 @param a The a value of the curve
38 @param modulus The modulus of the field the ECC curve is in
39 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
40 @return 0 on success
42 int
43 ecc_mulmod_timing (mpz_t k, ecc_point * G, ecc_point * R, mpz_t a, mpz_t modulus,
44 int map)
46 ecc_point *tG, *M[3];
47 int i, j, err;
48 int bit_to_read;
49 int mode;
51 if (k == NULL || G == NULL || R == NULL || modulus == NULL)
52 return -1;
54 /* alloc ram for window temps */
55 for (i = 0; i < 3; i++)
57 M[i] = ecc_new_point ();
58 if (M[i] == NULL)
60 for (j = 0; j < i; j++)
62 ecc_del_point (M[j]);
64 return -1;
68 /* make a copy of G incase R==G */
69 tG = ecc_new_point ();
70 if (tG == NULL)
72 err = -1;
73 goto done;
76 /* tG = G and convert to montgomery */
77 mpz_set (tG->x, G->x);
78 mpz_set (tG->y, G->y);
79 mpz_set (tG->z, G->z);
81 /* calc the M tab */
82 /* M[0] == G */
83 mpz_set (M[0]->x, tG->x);
84 mpz_set (M[0]->y, tG->y);
85 mpz_set (M[0]->z, tG->z);
86 /* M[1] == 2G */
87 if ((err = ecc_projective_dbl_point (tG, M[1], a, modulus)) != 0)
89 goto done;
92 /* setup sliding window */
93 mode = 0;
94 bit_to_read = mpz_size (k) * GMP_NUMB_BITS - 1;
96 /* perform ops */
97 for (;;)
99 /* grab next digit as required */
100 if (bit_to_read == -1)
101 break;
102 i = mpz_tstbit (k, bit_to_read--);
104 if (mode == 0 && i == 0)
106 /* dummy operations */
107 if ((err =
108 ecc_projective_add_point (M[0], M[1], M[2], a,
109 modulus)) != 0)
111 goto done;
113 if ((err =
114 ecc_projective_dbl_point (M[1], M[2], a, modulus)) != 0)
116 goto done;
118 continue;
121 if (mode == 0 && i == 1)
123 mode = 1;
124 /* dummy operations */
125 if ((err =
126 ecc_projective_add_point (M[0], M[1], M[2], a,
127 modulus)) != 0)
129 goto done;
131 if ((err =
132 ecc_projective_dbl_point (M[1], M[2], a, modulus)) != 0)
134 goto done;
136 continue;
139 if ((err =
140 ecc_projective_add_point (M[0], M[1], M[i ^ 1], a,
141 modulus)) != 0)
143 goto done;
145 if ((err = ecc_projective_dbl_point (M[i], M[i], a, modulus)) != 0)
147 goto done;
151 /* copy result out */
152 mpz_set (R->x, M[0]->x);
153 mpz_set (R->y, M[0]->y);
154 mpz_set (R->z, M[0]->z);
156 /* map R back from projective space */
157 if (map)
159 err = ecc_map (R, modulus);
161 else
163 err = 0;
165 done:
166 ecc_del_point (tG);
167 for (i = 0; i < 3; i++)
169 ecc_del_point (M[i]);
171 return err;
174 /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_mulmod_timing.c,v $ */
175 /* $Revision: 1.13 $ */
176 /* $Date: 2007/05/12 14:32:35 $ */