1 | #include "ge.h" |
2 | |
3 | static const fe d = { |
4 | #include "d.h" |
5 | } ; |
6 | |
7 | static const fe sqrtm1 = { |
8 | #include "sqrtm1.h" |
9 | } ; |
10 | |
11 | int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s) |
12 | { |
13 | fe u; |
14 | fe v; |
15 | fe v3; |
16 | fe vxx; |
17 | fe check; |
18 | |
19 | fe_frombytes(h->Y,s); |
20 | fe_1(h->Z); |
21 | fe_sq(u,h->Y); |
22 | fe_mul(v,u,d); |
23 | fe_sub(u,u,h->Z); /* u = y^2-1 */ |
24 | fe_add(v,v,h->Z); /* v = dy^2+1 */ |
25 | |
26 | fe_sq(v3,v); |
27 | fe_mul(v3,v3,v); /* v3 = v^3 */ |
28 | fe_sq(h->X,v3); |
29 | fe_mul(h->X,h->X,v); |
30 | fe_mul(h->X,h->X,u); /* x = uv^7 */ |
31 | |
32 | fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ |
33 | fe_mul(h->X,h->X,v3); |
34 | fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ |
35 | |
36 | fe_sq(vxx,h->X); |
37 | fe_mul(vxx,vxx,v); |
38 | fe_sub(check,vxx,u); /* vx^2-u */ |
39 | if (fe_isnonzero(check)) { |
40 | fe_add(check,vxx,u); /* vx^2+u */ |
41 | if (fe_isnonzero(check)) return -1; |
42 | fe_mul(h->X,h->X,sqrtm1); |
43 | } |
44 | |
45 | if (fe_isnegative(h->X) == (s[31] >> 7)) |
46 | fe_neg(h->X,h->X); |
47 | |
48 | fe_mul(h->T,h->X,h->Y); |
49 | return 0; |
50 | } |
51 | |