|
@@ -378,34 +378,20 @@ void decaf_nonuniform_map_to_curve ( |
|
|
decaf_point_t p, |
|
|
decaf_point_t p, |
|
|
const unsigned char ser[DECAF_SER_BYTES] |
|
|
const unsigned char ser[DECAF_SER_BYTES] |
|
|
) { |
|
|
) { |
|
|
/* |
|
|
|
|
|
sage: XXD = (u*r^2 + 1) * (d - u*r^2) * (1 - u*d*r^2) / (d+1) |
|
|
|
|
|
sage: factor(XX / (1/XXD)) |
|
|
|
|
|
(u*r^2 - d)^2 |
|
|
|
|
|
sage: factor((ey-1)/(ey+1)/(1/d * 1/XXD)) |
|
|
|
|
|
(u*d*r^2 - 1)^2 |
|
|
|
|
|
sage: factor(XX2 / (u*r^2/XXD)) |
|
|
|
|
|
(u*d*r^2 - 1)^2 |
|
|
|
|
|
sage: factor((ey2-1)/(ey2+1)/(1/d * u*r^2/XXD)) |
|
|
|
|
|
(u*r^2 - d)^2 |
|
|
|
|
|
*/ |
|
|
|
|
|
gf r,urr,a,b,c,dee,e,ur2_d,udr2_1; |
|
|
gf r,urr,a,b,c,dee,e,ur2_d,udr2_1; |
|
|
(void)gf_deser(r,ser); |
|
|
(void)gf_deser(r,ser); |
|
|
gf_canon(r); // just in case |
|
|
|
|
|
|
|
|
gf_canon(r); |
|
|
gf_sqr(a,r); |
|
|
gf_sqr(a,r); |
|
|
|
|
|
|
|
|
gf_mlw(urr,a,QUADRATIC_NONRESIDUE); // urr = u*r^2 |
|
|
|
|
|
|
|
|
gf_mlw(urr,a,QUADRATIC_NONRESIDUE); |
|
|
gf_mlw(dee,ONE,EDWARDS_D); |
|
|
gf_mlw(dee,ONE,EDWARDS_D); |
|
|
|
|
|
|
|
|
gf_add(a,urr,ONE); |
|
|
gf_add(a,urr,ONE); |
|
|
gf_sub(ur2_d,dee,urr); // ur2_d = -(ur^2-d) |
|
|
|
|
|
|
|
|
gf_sub(ur2_d,dee,urr); |
|
|
gf_mul(c,a,ur2_d); |
|
|
gf_mul(c,a,ur2_d); |
|
|
gf_mlw(b,urr,-EDWARDS_D); |
|
|
gf_mlw(b,urr,-EDWARDS_D); |
|
|
gf_add(udr2_1,b,ONE); // udr2_1 = -(udr^2-1) |
|
|
|
|
|
|
|
|
gf_add(udr2_1,b,ONE); |
|
|
gf_mul(a,c,udr2_1); |
|
|
gf_mul(a,c,udr2_1); |
|
|
gf_mlw(c,a,EDWARDS_D+1); // c = (u*r^2 + 1) * (d - u*r^2) * (1 - u*d*r^2) * (d+1) |
|
|
|
|
|
|
|
|
|
|
|
gf_isqrt(b,c); // FIELD: if 5 mod 8, multiply result by u. |
|
|
|
|
|
|
|
|
gf_mlw(c,a,EDWARDS_D+1); |
|
|
|
|
|
gf_isqrt(b,c); /* FIELD: if 5 mod 8, multiply result by u. */ |
|
|
gf_sqr(a,b); |
|
|
gf_sqr(a,b); |
|
|
gf_mul(e,a,c); |
|
|
gf_mul(e,a,c); |
|
|
mask_t square = gf_eq(e,ONE); |
|
|
mask_t square = gf_eq(e,ONE); |
|
@@ -413,29 +399,15 @@ void decaf_nonuniform_map_to_curve ( |
|
|
cond_sel(b,a,b,square); |
|
|
cond_sel(b,a,b,square); |
|
|
cond_neg(b,hibit(b)); |
|
|
cond_neg(b,hibit(b)); |
|
|
gf_mlw(a,b,EDWARDS_D+1); |
|
|
gf_mlw(a,b,EDWARDS_D+1); |
|
|
/* Here: a = sqrt( (d+1) / (ur^2?) * (u*r^2 + 1) * (d - u*r^2) * (1 - u*d*r^2)) */ |
|
|
|
|
|
|
|
|
|
|
|
cond_swap(ur2_d,udr2_1,~square); |
|
|
cond_swap(ur2_d,udr2_1,~square); |
|
|
gf_mul(e,ur2_d,a); |
|
|
gf_mul(e,ur2_d,a); |
|
|
gf_mul(b,udr2_1,a); |
|
|
gf_mul(b,udr2_1,a); |
|
|
gf_sqr(c,b); |
|
|
gf_sqr(c,b); |
|
|
|
|
|
|
|
|
/* Here: |
|
|
|
|
|
* ed_x = 2e/(1-e^2) |
|
|
|
|
|
* c = * (ed_y-1)/(ed_y+1) |
|
|
|
|
|
* |
|
|
|
|
|
* Special cases: |
|
|
|
|
|
* e^2 = 1: impossible for cofactor-4 curves (would isogenize to order-4 point) |
|
|
|
|
|
* e = 0 <-> also c = 0: maps to (0,1), which is fine. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
gf_sqr(a,e); |
|
|
gf_sqr(a,e); |
|
|
gf_sub(a,ONE,a); |
|
|
gf_sub(a,ONE,a); |
|
|
gf_add(e,e,e); |
|
|
gf_add(e,e,e); |
|
|
|
|
|
|
|
|
gf_add(b,dee,c); |
|
|
gf_add(b,dee,c); |
|
|
gf_sub(c,dee,c); |
|
|
gf_sub(c,dee,c); |
|
|
|
|
|
|
|
|
gf_mul(p->x,e,c); |
|
|
gf_mul(p->x,e,c); |
|
|
gf_mul(p->z,a,c); |
|
|
gf_mul(p->z,a,c); |
|
|
gf_mul(p->y,b,a); |
|
|
gf_mul(p->y,b,a); |
|
|