]>
Commit | Line | Data |
---|---|---|
7a4b7691 PW |
1 | #ifndef _SECP256K1_GROUP_IMPL_H_ |
2 | #define _SECP256K1_GROUP_IMPL_H_ | |
3 | ||
f11ff5be | 4 | #include <string.h> |
607884fc | 5 | |
7a4b7691 PW |
6 | #include "../num.h" |
7 | #include "../field.h" | |
8 | #include "../group.h" | |
607884fc | 9 | |
f11ff5be PW |
10 | void static secp256k1_ge_set_infinity(secp256k1_ge_t *r) { |
11 | r->infinity = 1; | |
607884fc PW |
12 | } |
13 | ||
f11ff5be PW |
14 | void static secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { |
15 | r->infinity = 0; | |
16 | r->x = *x; | |
17 | r->y = *y; | |
607884fc PW |
18 | } |
19 | ||
f11ff5be PW |
20 | int static secp256k1_ge_is_infinity(const secp256k1_ge_t *a) { |
21 | return a->infinity; | |
607884fc PW |
22 | } |
23 | ||
f11ff5be PW |
24 | void static secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) { |
25 | r->infinity = a->infinity; | |
26 | r->x = a->x; | |
27 | r->y = a->y; | |
28 | secp256k1_fe_normalize(&r->y); | |
29 | secp256k1_fe_negate(&r->y, &r->y, 1); | |
607884fc PW |
30 | } |
31 | ||
f11ff5be PW |
32 | void static secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a) { |
33 | char cx[65]; int lx=65; | |
34 | char cy[65]; int ly=65; | |
35 | secp256k1_fe_get_hex(cx, &lx, &a->x); | |
36 | secp256k1_fe_get_hex(cy, &ly, &a->y); | |
37 | lx = strlen(cx); | |
38 | ly = strlen(cy); | |
39 | int len = lx + ly + 3 + 1; | |
40 | if (*rlen < len) { | |
41 | *rlen = len; | |
42 | return; | |
43 | } | |
44 | *rlen = len; | |
45 | r[0] = '('; | |
46 | memcpy(r+1, cx, lx); | |
47 | r[1+lx] = ','; | |
48 | memcpy(r+2+lx, cy, ly); | |
49 | r[2+lx+ly] = ')'; | |
50 | r[3+lx+ly] = 0; | |
51 | } | |
52 | ||
53 | void static secp256k1_ge_set_gej(secp256k1_ge_t *r, secp256k1_gej_t *a) { | |
54 | secp256k1_fe_inv_var(&a->z, &a->z); | |
55 | secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); | |
56 | secp256k1_fe_t z3; secp256k1_fe_mul(&z3, &a->z, &z2); | |
57 | secp256k1_fe_mul(&a->x, &a->x, &z2); | |
58 | secp256k1_fe_mul(&a->y, &a->y, &z3); | |
59 | secp256k1_fe_set_int(&a->z, 1); | |
60 | r->infinity = a->infinity; | |
61 | r->x = a->x; | |
62 | r->y = a->y; | |
607884fc PW |
63 | } |
64 | ||
f11ff5be PW |
65 | void static secp256k1_gej_set_infinity(secp256k1_gej_t *r) { |
66 | r->infinity = 1; | |
607884fc PW |
67 | } |
68 | ||
f11ff5be PW |
69 | void static secp256k1_gej_set_xy(secp256k1_gej_t *r, const secp256k1_fe_t *x, const secp256k1_fe_t *y) { |
70 | r->infinity = 0; | |
71 | r->x = *x; | |
72 | r->y = *y; | |
73 | secp256k1_fe_set_int(&r->z, 1); | |
607884fc PW |
74 | } |
75 | ||
764332d0 | 76 | void static secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) { |
f11ff5be PW |
77 | r->x = *x; |
78 | secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, x); | |
79 | secp256k1_fe_t x3; secp256k1_fe_mul(&x3, x, &x2); | |
eb0be8ee | 80 | r->infinity = 0; |
f11ff5be PW |
81 | secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); |
82 | secp256k1_fe_add(&c, &x3); | |
83 | secp256k1_fe_sqrt(&r->y, &c); | |
f11ff5be PW |
84 | secp256k1_fe_normalize(&r->y); |
85 | if (secp256k1_fe_is_odd(&r->y) != odd) | |
86 | secp256k1_fe_negate(&r->y, &r->y, 1); | |
910d0de4 | 87 | } |
607884fc | 88 | |
f11ff5be PW |
89 | void static secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a) { |
90 | r->infinity = a->infinity; | |
91 | r->x = a->x; | |
92 | r->y = a->y; | |
93 | secp256k1_fe_set_int(&r->z, 1); | |
910d0de4 | 94 | } |
607884fc | 95 | |
f11ff5be PW |
96 | void static secp256k1_gej_get_x(secp256k1_fe_t *r, const secp256k1_gej_t *a) { |
97 | secp256k1_fe_t zi2; secp256k1_fe_inv_var(&zi2, &a->z); secp256k1_fe_sqr(&zi2, &zi2); | |
98 | secp256k1_fe_mul(r, &a->x, &zi2); | |
910d0de4 | 99 | } |
607884fc | 100 | |
f11ff5be PW |
101 | void static secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) { |
102 | r->infinity = a->infinity; | |
103 | r->x = a->x; | |
104 | r->y = a->y; | |
105 | r->z = a->z; | |
106 | secp256k1_fe_normalize(&r->y); | |
107 | secp256k1_fe_negate(&r->y, &r->y, 1); | |
607884fc PW |
108 | } |
109 | ||
f11ff5be PW |
110 | int static secp256k1_gej_is_infinity(const secp256k1_gej_t *a) { |
111 | return a->infinity; | |
0a07e62f PW |
112 | } |
113 | ||
f11ff5be PW |
114 | int static secp256k1_gej_is_valid(const secp256k1_gej_t *a) { |
115 | if (a->infinity) | |
eb0be8ee | 116 | return 0; |
607884fc PW |
117 | // y^2 = x^3 + 7 |
118 | // (Y/Z^3)^2 = (X/Z^2)^3 + 7 | |
119 | // Y^2 / Z^6 = X^3 / Z^6 + 7 | |
120 | // Y^2 = X^3 + 7*Z^6 | |
f11ff5be PW |
121 | secp256k1_fe_t y2; secp256k1_fe_sqr(&y2, &a->y); |
122 | secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); | |
123 | secp256k1_fe_t z2; secp256k1_fe_sqr(&z2, &a->z); | |
910d0de4 PW |
124 | secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2); |
125 | secp256k1_fe_mul_int(&z6, 7); | |
126 | secp256k1_fe_add(&x3, &z6); | |
127 | secp256k1_fe_normalize(&y2); | |
128 | secp256k1_fe_normalize(&x3); | |
129 | return secp256k1_fe_equal(&y2, &x3); | |
607884fc PW |
130 | } |
131 | ||
764332d0 PW |
132 | int static secp256k1_ge_is_valid(const secp256k1_ge_t *a) { |
133 | if (a->infinity) | |
134 | return 0; | |
135 | // y^2 = x^3 + 7 | |
136 | secp256k1_fe_t y2; secp256k1_fe_sqr(&y2, &a->y); | |
137 | secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x); | |
138 | secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7); | |
139 | secp256k1_fe_add(&x3, &c); | |
140 | secp256k1_fe_normalize(&y2); | |
141 | secp256k1_fe_normalize(&x3); | |
142 | return secp256k1_fe_equal(&y2, &x3); | |
143 | } | |
144 | ||
f11ff5be PW |
145 | void static secp256k1_gej_double(secp256k1_gej_t *r, const secp256k1_gej_t *a) { |
146 | secp256k1_fe_t t5 = a->y; | |
910d0de4 | 147 | secp256k1_fe_normalize(&t5); |
f11ff5be | 148 | if (a->infinity || secp256k1_fe_is_zero(&t5)) { |
eb0be8ee | 149 | r->infinity = 1; |
607884fc PW |
150 | return; |
151 | } | |
152 | ||
910d0de4 | 153 | secp256k1_fe_t t1,t2,t3,t4; |
f11ff5be PW |
154 | secp256k1_fe_mul(&r->z, &t5, &a->z); |
155 | secp256k1_fe_mul_int(&r->z, 2); // Z' = 2*Y*Z (2) | |
156 | secp256k1_fe_sqr(&t1, &a->x); | |
157 | secp256k1_fe_mul_int(&t1, 3); // T1 = 3*X^2 (3) | |
158 | secp256k1_fe_sqr(&t2, &t1); // T2 = 9*X^4 (1) | |
910d0de4 | 159 | secp256k1_fe_sqr(&t3, &t5); |
f11ff5be | 160 | secp256k1_fe_mul_int(&t3, 2); // T3 = 2*Y^2 (2) |
910d0de4 | 161 | secp256k1_fe_sqr(&t4, &t3); |
f11ff5be PW |
162 | secp256k1_fe_mul_int(&t4, 2); // T4 = 8*Y^4 (2) |
163 | secp256k1_fe_mul(&t3, &a->x, &t3); // T3 = 2*X*Y^2 (1) | |
164 | r->x = t3; | |
165 | secp256k1_fe_mul_int(&r->x, 4); // X' = 8*X*Y^2 (4) | |
166 | secp256k1_fe_negate(&r->x, &r->x, 4); // X' = -8*X*Y^2 (5) | |
167 | secp256k1_fe_add(&r->x, &t2); // X' = 9*X^4 - 8*X*Y^2 (6) | |
168 | secp256k1_fe_negate(&t2, &t2, 1); // T2 = -9*X^4 (2) | |
169 | secp256k1_fe_mul_int(&t3, 6); // T3 = 12*X*Y^2 (6) | |
170 | secp256k1_fe_add(&t3, &t2); // T3 = 12*X*Y^2 - 9*X^4 (8) | |
171 | secp256k1_fe_mul(&r->y, &t1, &t3); // Y' = 36*X^3*Y^2 - 27*X^6 (1) | |
172 | secp256k1_fe_negate(&t2, &t4, 2); // T2 = -8*Y^4 (3) | |
173 | secp256k1_fe_add(&r->y, &t2); // Y' = 36*X^3*Y^2 - 27*X^6 - 8*Y^4 (4) | |
eb0be8ee | 174 | r->infinity = 0; |
607884fc PW |
175 | } |
176 | ||
f11ff5be PW |
177 | void static secp256k1_gej_add(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_t *b) { |
178 | if (a->infinity) { | |
179 | *r = *b; | |
607884fc PW |
180 | return; |
181 | } | |
f11ff5be PW |
182 | if (b->infinity) { |
183 | *r = *a; | |
607884fc PW |
184 | return; |
185 | } | |
eb0be8ee | 186 | r->infinity = 0; |
f11ff5be PW |
187 | secp256k1_fe_t z22; secp256k1_fe_sqr(&z22, &b->z); |
188 | secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); | |
189 | secp256k1_fe_t u1; secp256k1_fe_mul(&u1, &a->x, &z22); | |
190 | secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); | |
191 | secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z); | |
192 | secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); | |
910d0de4 PW |
193 | secp256k1_fe_normalize(&u1); |
194 | secp256k1_fe_normalize(&u2); | |
195 | if (secp256k1_fe_equal(&u1, &u2)) { | |
196 | secp256k1_fe_normalize(&s1); | |
197 | secp256k1_fe_normalize(&s2); | |
198 | if (secp256k1_fe_equal(&s1, &s2)) { | |
f11ff5be | 199 | secp256k1_gej_double(r, a); |
607884fc | 200 | } else { |
eb0be8ee | 201 | r->infinity = 1; |
607884fc PW |
202 | } |
203 | return; | |
204 | } | |
910d0de4 | 205 | secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); |
f11ff5be PW |
206 | secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); |
207 | secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); | |
910d0de4 PW |
208 | secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); |
209 | secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); | |
f11ff5be | 210 | secp256k1_fe_mul(&r->z, &a->z, &b->z); secp256k1_fe_mul(&r->z, &r->z, &h); |
910d0de4 | 211 | secp256k1_fe_t t; secp256k1_fe_mul(&t, &u1, &h2); |
f11ff5be PW |
212 | r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); |
213 | secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); | |
910d0de4 | 214 | secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); |
f11ff5be | 215 | secp256k1_fe_add(&r->y, &h3); |
607884fc PW |
216 | } |
217 | ||
f11ff5be PW |
218 | void static secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_ge_t *b) { |
219 | if (a->infinity) { | |
220 | r->infinity = b->infinity; | |
221 | r->x = b->x; | |
222 | r->y = b->y; | |
223 | secp256k1_fe_set_int(&r->z, 1); | |
607884fc PW |
224 | return; |
225 | } | |
f11ff5be PW |
226 | if (b->infinity) { |
227 | *r = *a; | |
607884fc PW |
228 | return; |
229 | } | |
eb0be8ee | 230 | r->infinity = 0; |
f11ff5be PW |
231 | secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z); |
232 | secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); | |
233 | secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12); | |
234 | secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); | |
235 | secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z); | |
910d0de4 PW |
236 | secp256k1_fe_normalize(&u1); |
237 | secp256k1_fe_normalize(&u2); | |
238 | if (secp256k1_fe_equal(&u1, &u2)) { | |
239 | secp256k1_fe_normalize(&s1); | |
240 | secp256k1_fe_normalize(&s2); | |
241 | if (secp256k1_fe_equal(&s1, &s2)) { | |
f11ff5be | 242 | secp256k1_gej_double(r, a); |
607884fc | 243 | } else { |
eb0be8ee | 244 | r->infinity = 1; |
607884fc PW |
245 | } |
246 | return; | |
247 | } | |
910d0de4 | 248 | secp256k1_fe_t h; secp256k1_fe_negate(&h, &u1, 1); secp256k1_fe_add(&h, &u2); |
f11ff5be PW |
249 | secp256k1_fe_t i; secp256k1_fe_negate(&i, &s1, 1); secp256k1_fe_add(&i, &s2); |
250 | secp256k1_fe_t i2; secp256k1_fe_sqr(&i2, &i); | |
910d0de4 PW |
251 | secp256k1_fe_t h2; secp256k1_fe_sqr(&h2, &h); |
252 | secp256k1_fe_t h3; secp256k1_fe_mul(&h3, &h, &h2); | |
f11ff5be | 253 | r->z = a->z; secp256k1_fe_mul(&r->z, &r->z, &h); |
910d0de4 | 254 | secp256k1_fe_t t; secp256k1_fe_mul(&t, &u1, &h2); |
f11ff5be PW |
255 | r->x = t; secp256k1_fe_mul_int(&r->x, 2); secp256k1_fe_add(&r->x, &h3); secp256k1_fe_negate(&r->x, &r->x, 3); secp256k1_fe_add(&r->x, &i2); |
256 | secp256k1_fe_negate(&r->y, &r->x, 5); secp256k1_fe_add(&r->y, &t); secp256k1_fe_mul(&r->y, &r->y, &i); | |
910d0de4 | 257 | secp256k1_fe_mul(&h3, &h3, &s1); secp256k1_fe_negate(&h3, &h3, 1); |
f11ff5be | 258 | secp256k1_fe_add(&r->y, &h3); |
607884fc PW |
259 | } |
260 | ||
f11ff5be PW |
261 | void static secp256k1_gej_get_hex(char *r, int *rlen, const secp256k1_gej_t *a) { |
262 | secp256k1_gej_t c = *a; | |
263 | secp256k1_ge_t t; secp256k1_ge_set_gej(&t, &c); | |
264 | secp256k1_ge_get_hex(r, rlen, &t); | |
607884fc PW |
265 | } |
266 | ||
f11ff5be PW |
267 | void static secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) { |
268 | const secp256k1_fe_t *beta = &secp256k1_ge_consts->beta; | |
269 | *r = *a; | |
270 | secp256k1_fe_mul(&r->x, &r->x, beta); | |
607884fc PW |
271 | } |
272 | ||
f11ff5be PW |
273 | void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, const secp256k1_num_t *a) { |
274 | const secp256k1_ge_consts_t *c = secp256k1_ge_consts; | |
4adf6b2a PW |
275 | secp256k1_num_t bnc1, bnc2, bnt1, bnt2, bnn2; |
276 | ||
277 | secp256k1_num_init(&bnc1); | |
278 | secp256k1_num_init(&bnc2); | |
279 | secp256k1_num_init(&bnt1); | |
280 | secp256k1_num_init(&bnt2); | |
281 | secp256k1_num_init(&bnn2); | |
282 | ||
f11ff5be | 283 | secp256k1_num_copy(&bnn2, &c->order); |
4adf6b2a PW |
284 | secp256k1_num_shift(&bnn2, 1); |
285 | ||
f11ff5be | 286 | secp256k1_num_mul(&bnc1, a, &c->a1b2); |
4adf6b2a | 287 | secp256k1_num_add(&bnc1, &bnc1, &bnn2); |
f11ff5be | 288 | secp256k1_num_div(&bnc1, &bnc1, &c->order); |
4adf6b2a | 289 | |
f11ff5be | 290 | secp256k1_num_mul(&bnc2, a, &c->b1); |
4adf6b2a | 291 | secp256k1_num_add(&bnc2, &bnc2, &bnn2); |
f11ff5be | 292 | secp256k1_num_div(&bnc2, &bnc2, &c->order); |
4adf6b2a | 293 | |
f11ff5be PW |
294 | secp256k1_num_mul(&bnt1, &bnc1, &c->a1b2); |
295 | secp256k1_num_mul(&bnt2, &bnc2, &c->a2); | |
4adf6b2a | 296 | secp256k1_num_add(&bnt1, &bnt1, &bnt2); |
f11ff5be PW |
297 | secp256k1_num_sub(r1, a, &bnt1); |
298 | secp256k1_num_mul(&bnt1, &bnc1, &c->b1); | |
299 | secp256k1_num_mul(&bnt2, &bnc2, &c->a1b2); | |
300 | secp256k1_num_sub(r2, &bnt1, &bnt2); | |
4adf6b2a PW |
301 | |
302 | secp256k1_num_free(&bnc1); | |
303 | secp256k1_num_free(&bnc2); | |
304 | secp256k1_num_free(&bnt1); | |
305 | secp256k1_num_free(&bnt2); | |
306 | secp256k1_num_free(&bnn2); | |
607884fc PW |
307 | } |
308 | ||
f11ff5be PW |
309 | |
310 | void static secp256k1_ge_start(void) { | |
ff29b855 PW |
311 | static const unsigned char secp256k1_ge_consts_order[] = { |
312 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, | |
313 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, | |
314 | 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, | |
315 | 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41 | |
316 | }; | |
317 | static const unsigned char secp256k1_ge_consts_g_x[] = { | |
318 | 0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC, | |
319 | 0x55,0xA0,0x62,0x95,0xCE,0x87,0x0B,0x07, | |
320 | 0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9, | |
321 | 0x59,0xF2,0x81,0x5B,0x16,0xF8,0x17,0x98 | |
322 | }; | |
323 | static const unsigned char secp256k1_ge_consts_g_y[] = { | |
324 | 0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65, | |
325 | 0x5D,0xA4,0xFB,0xFC,0x0E,0x11,0x08,0xA8, | |
326 | 0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19, | |
327 | 0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8 | |
328 | }; | |
329 | // properties of secp256k1's efficiently computable endomorphism | |
330 | static const unsigned char secp256k1_ge_consts_lambda[] = { | |
331 | 0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0, | |
332 | 0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a, | |
333 | 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78, | |
334 | 0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72 | |
335 | }; | |
336 | static const unsigned char secp256k1_ge_consts_beta[] = { | |
337 | 0x7a,0xe9,0x6a,0x2b,0x65,0x7c,0x07,0x10, | |
338 | 0x6e,0x64,0x47,0x9e,0xac,0x34,0x34,0xe9, | |
339 | 0x9c,0xf0,0x49,0x75,0x12,0xf5,0x89,0x95, | |
340 | 0xc1,0x39,0x6c,0x28,0x71,0x95,0x01,0xee | |
341 | }; | |
342 | static const unsigned char secp256k1_ge_consts_a1b2[] = { | |
343 | 0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd, | |
344 | 0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15 | |
345 | }; | |
346 | static const unsigned char secp256k1_ge_consts_b1[] = { | |
347 | 0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28, | |
348 | 0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3 | |
349 | }; | |
350 | static const unsigned char secp256k1_ge_consts_a2[] = { | |
351 | 0x01, | |
352 | 0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6, | |
353 | 0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8 | |
354 | }; | |
f11ff5be PW |
355 | if (secp256k1_ge_consts == NULL) { |
356 | secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)malloc(sizeof(secp256k1_ge_consts_t)); | |
357 | secp256k1_num_init(&ret->order); | |
358 | secp256k1_num_init(&ret->lambda); | |
359 | secp256k1_num_init(&ret->a1b2); | |
360 | secp256k1_num_init(&ret->a2); | |
361 | secp256k1_num_init(&ret->b1); | |
362 | secp256k1_num_set_bin(&ret->order, secp256k1_ge_consts_order, sizeof(secp256k1_ge_consts_order)); | |
363 | secp256k1_num_set_bin(&ret->lambda, secp256k1_ge_consts_lambda, sizeof(secp256k1_ge_consts_lambda)); | |
364 | secp256k1_num_set_bin(&ret->a1b2, secp256k1_ge_consts_a1b2, sizeof(secp256k1_ge_consts_a1b2)); | |
365 | secp256k1_num_set_bin(&ret->a2, secp256k1_ge_consts_a2, sizeof(secp256k1_ge_consts_a2)); | |
366 | secp256k1_num_set_bin(&ret->b1, secp256k1_ge_consts_b1, sizeof(secp256k1_ge_consts_b1)); | |
367 | secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta); | |
368 | secp256k1_fe_t g_x, g_y; | |
369 | secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x); | |
370 | secp256k1_fe_set_b32(&g_y, secp256k1_ge_consts_g_y); | |
371 | secp256k1_ge_set_xy(&ret->g, &g_x, &g_y); | |
372 | secp256k1_ge_consts = ret; | |
373 | } | |
374 | } | |
375 | ||
376 | void static secp256k1_ge_stop(void) { | |
377 | if (secp256k1_ge_consts != NULL) { | |
378 | secp256k1_ge_consts_t *c = (secp256k1_ge_consts_t*)secp256k1_ge_consts; | |
379 | secp256k1_num_free(&c->order); | |
380 | secp256k1_num_free(&c->lambda); | |
381 | secp256k1_num_free(&c->a1b2); | |
382 | secp256k1_num_free(&c->a2); | |
383 | secp256k1_num_free(&c->b1); | |
384 | free((void*)c); | |
385 | secp256k1_ge_consts = NULL; | |
386 | } | |
387 | } | |
7a4b7691 PW |
388 | |
389 | #endif |