/src/relic/src/ed/relic_ed_dbl.c
Line | Count | Source |
1 | | /* |
2 | | * RELIC is an Efficient LIbrary for Cryptography |
3 | | * Copyright (c) 2014 RELIC Authors |
4 | | * |
5 | | * This file is part of RELIC. RELIC is legal property of its developers, |
6 | | * whose names are not listed here. Please refer to the COPYRIGHT file |
7 | | * for contact information. |
8 | | * |
9 | | * RELIC is free software; you can redistribute it and/or modify it under the |
10 | | * terms of the version 2.1 (or later) of the GNU Lesser General Public License |
11 | | * as published by the Free Software Foundation; or version 2.0 of the Apache |
12 | | * License as published by the Apache Software Foundation. See the LICENSE files |
13 | | * for more details. |
14 | | * |
15 | | * RELIC is distributed in the hope that it will be useful, but WITHOUT ANY |
16 | | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
17 | | * A PARTICULAR PURPOSE. See the LICENSE files for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public or the |
20 | | * Apache License along with RELIC. If not, see <https://www.gnu.org/licenses/> |
21 | | * or <https://www.apache.org/licenses/>. |
22 | | */ |
23 | | |
24 | | /** |
25 | | * @file |
26 | | * |
27 | | * Implementation of the point doubling on prime elliptic twisted Edwards curves. |
28 | | * |
29 | | * @version $Id$ |
30 | | * @ingroup ed |
31 | | */ |
32 | | |
33 | | #include "relic_core.h" |
34 | | #include "relic_label.h" |
35 | | |
36 | | /*============================================================================*/ |
37 | | /* Public definitions */ |
38 | | /*============================================================================*/ |
39 | | |
40 | | #if ED_ADD == BASIC || !defined(STRIP) |
41 | | |
42 | 0 | void ed_dbl_basic(ed_t r, const ed_t p) { |
43 | 0 | fp_t t0, t1, t2; |
44 | |
|
45 | 0 | fp_null(t0); |
46 | 0 | fp_null(t1); |
47 | 0 | fp_null(t2); |
48 | |
|
49 | 0 | RLC_TRY { |
50 | 0 | fp_new(t0); |
51 | 0 | fp_new(t1); |
52 | 0 | fp_new(t2); |
53 | | |
54 | | /* x3 = (x1*y1+y1*x1)/(1+d*x1*x1*y1*y1) |
55 | | * y3 = (y1*y1-a*x1*x1)/(1-d*x1*x1*y1*y1) */ |
56 | |
|
57 | 0 | fp_mul(t0, p->x, p->y); |
58 | 0 | fp_sqr(t1, t0); |
59 | |
|
60 | 0 | fp_mul(t1, t1, core_get()->ed_d); |
61 | 0 | fp_add_dig(t2, t1, 1); |
62 | 0 | fp_inv(t2, t2); |
63 | 0 | fp_sub_dig(t1, t1, 1); |
64 | 0 | fp_neg(t1, t1); |
65 | 0 | fp_inv(t1, t1); |
66 | |
|
67 | 0 | fp_dbl(t0, t0); |
68 | 0 | fp_mul(t0, t0, t2); |
69 | |
|
70 | 0 | fp_sqr(t2, p->x); |
71 | 0 | fp_mul(t2, t2, core_get()->ed_a); |
72 | 0 | fp_sqr(r->y, p->y); |
73 | 0 | fp_sub(r->y, r->y, t2); |
74 | 0 | fp_mul(r->y, r->y, t1); |
75 | |
|
76 | 0 | fp_copy(r->x, t0); |
77 | 0 | fp_copy(r->z, p->z); |
78 | |
|
79 | 0 | r->coord = BASIC; |
80 | 0 | } |
81 | 0 | RLC_CATCH_ANY { |
82 | 0 | RLC_THROW(ERR_CAUGHT); |
83 | 0 | } |
84 | 0 | RLC_FINALLY { |
85 | 0 | fp_free(t0); |
86 | 0 | fp_free(t1); |
87 | 0 | fp_free(t2); |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | | #endif /* ED_ADD == BASIC */ |
92 | | |
93 | | #if ED_ADD == PROJC || !defined(STRIP) |
94 | | |
95 | 0 | void ed_dbl_projc(ed_t r, const ed_t p) { |
96 | 0 | fp_t t0, t1, t2, t3, t4, t5, t6; |
97 | |
|
98 | 0 | fp_null(t0); |
99 | 0 | fp_null(t1); |
100 | 0 | fp_null(t2); |
101 | 0 | fp_null(t3); |
102 | 0 | fp_null(t4); |
103 | 0 | fp_null(t5); |
104 | 0 | fp_null(t6); |
105 | |
|
106 | 0 | RLC_TRY { |
107 | 0 | fp_new(t0); |
108 | 0 | fp_new(t1); |
109 | 0 | fp_new(t2); |
110 | 0 | fp_new(t3); |
111 | 0 | fp_new(t4); |
112 | 0 | fp_new(t5); |
113 | 0 | fp_new(t6); |
114 | | |
115 | | // 3M + 4S + 1D + 7add |
116 | | |
117 | | /* B = (x1 + y1)^2 */ |
118 | 0 | fp_add(t0, p->x, p->y); |
119 | 0 | fp_sqr(t0, t0); |
120 | | |
121 | | /* C = x1^2 */ |
122 | 0 | fp_sqr(t1, p->x); |
123 | | |
124 | | /* D = y1^2 */ |
125 | 0 | fp_sqr(t2, p->y); |
126 | | |
127 | | /* E = a * C */ |
128 | 0 | fp_mul(t3, core_get()->ed_a, t1); |
129 | | |
130 | | /* F = E + D, H = Z^2 */ |
131 | 0 | fp_add(t4, t3, t2); |
132 | 0 | fp_sqr(t5, p->z); |
133 | | |
134 | | // J = F - 2H |
135 | 0 | fp_dbl(t6, t5); |
136 | 0 | fp_sub(t6, t4, t6); |
137 | | |
138 | | // x3 = (B - C - D) * J |
139 | 0 | fp_sub(r->x, t0, t1); |
140 | 0 | fp_sub(r->x, r->x, t2); |
141 | 0 | fp_mul(r->x, r->x, t6); |
142 | | |
143 | | // x3 = F * (E - D) |
144 | 0 | fp_sub(r->y, t3, t2); |
145 | 0 | fp_mul(r->y, t4, r->y); |
146 | | |
147 | | /* x3 = F * J */ |
148 | 0 | fp_mul(r->z, t4, t6); |
149 | |
|
150 | 0 | r->coord = PROJC; |
151 | 0 | } RLC_CATCH_ANY { |
152 | 0 | RLC_THROW(ERR_CAUGHT); |
153 | 0 | } RLC_FINALLY { |
154 | 0 | fp_free(t0); |
155 | 0 | fp_free(t1); |
156 | 0 | fp_free(t2); |
157 | 0 | fp_free(t3); |
158 | 0 | fp_free(t4); |
159 | 0 | fp_free(t5); |
160 | 0 | fp_free(t6); |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | | #endif /* ED_PROJC */ |
165 | | |
166 | | #if ED_ADD == EXTND || !defined(STRIP) |
167 | | |
168 | 0 | void ed_dbl_extnd(ed_t r, const ed_t p) { |
169 | 0 | fp_t t0, t1, t2, t3, t4; |
170 | |
|
171 | 0 | fp_null(t0); |
172 | 0 | fp_null(t1); |
173 | 0 | fp_null(t2); |
174 | 0 | fp_null(t3); |
175 | 0 | fp_null(t4); |
176 | |
|
177 | 0 | RLC_TRY { |
178 | 0 | fp_new(t0); |
179 | 0 | fp_new(t1); |
180 | 0 | fp_new(t2); |
181 | 0 | fp_new(t3); |
182 | 0 | fp_new(t4); |
183 | | |
184 | | // efd: dbl-2008-hwcd, rfc edition |
185 | | // 4M + 4S + 1D + 7add |
186 | | |
187 | | /* A = X^2, B = Y^2 */ |
188 | 0 | fp_sqr(t0, p->x); |
189 | 0 | fp_sqr(t1, p->y); |
190 | | |
191 | | /* C = 2 * Z^2 */ |
192 | 0 | fp_sqr(r->z, p->z); |
193 | 0 | fp_dbl(r->z, r->z); |
194 | | |
195 | | /* D = a * A */ |
196 | 0 | fp_mul(r->t, core_get()->ed_a, t0); |
197 | | |
198 | | /* E = (X + Y) ^ 2 - A - B */ |
199 | 0 | fp_add(t2, p->x, p->y); |
200 | 0 | fp_sqr(t2, t2); |
201 | 0 | fp_sub(t2, t2, t0); |
202 | 0 | fp_sub(t2, t2, t1); |
203 | | |
204 | | /* G = D + B, F = G - C, H = D - B */ |
205 | 0 | fp_add(t4, r->t, t1); |
206 | 0 | fp_sub(t3, t4, r->z); |
207 | 0 | fp_sub(r->z, r->t, t1); |
208 | | |
209 | | /* X = E * F */ |
210 | 0 | fp_mul(r->x, t2, t3); |
211 | | /* Y = G * H */ |
212 | 0 | fp_mul(r->y, t4, r->z); |
213 | | /* T = E * H */ |
214 | 0 | fp_mul(r->t, t2, r->z); |
215 | | /* Z = F * G */ |
216 | 0 | fp_mul(r->z, t3, t4); |
217 | 0 | r->coord = EXTND; |
218 | 0 | } RLC_CATCH_ANY { |
219 | 0 | RLC_THROW(ERR_CAUGHT); |
220 | 0 | } RLC_FINALLY { |
221 | 0 | fp_free(t0); |
222 | 0 | fp_free(t1); |
223 | 0 | fp_free(t2); |
224 | 0 | fp_free(t3); |
225 | 0 | fp_free(t4); |
226 | 0 | } |
227 | 0 | } |
228 | | |
229 | | #endif /* ED_EXTND */ |