Coverage Report

Created: 2026-06-07 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 */