@@ -740,40 +740,58 @@ void decaf_448_point_from_hash_nonuniform ( | |||||
decaf_448_point_t p, | decaf_448_point_t p, | ||||
const unsigned char ser[DECAF_448_SER_BYTES] | const unsigned char ser[DECAF_448_SER_BYTES] | ||||
) { | ) { | ||||
gf r,urr,a,b,c,dee,e,ur2_d,udr2_1; | |||||
(void)gf_deser(r,ser); | |||||
gf_canon(r); | |||||
gf_sqr(a,r); | |||||
gf_mlw(urr,a,QUADRATIC_NONRESIDUE); | |||||
gf r0,r,a,b,c,dee,D,N,e; | |||||
(void)gf_deser(r0,ser); | |||||
gf_canon(r0); | |||||
gf_sqr(a,r0); | |||||
gf_mlw(r,a,QUADRATIC_NONRESIDUE); | |||||
gf_mlw(dee,ONE,EDWARDS_D); | gf_mlw(dee,ONE,EDWARDS_D); | ||||
gf_add(a,urr,ONE); | |||||
gf_sub(ur2_d,dee,urr); | |||||
gf_mul(c,a,ur2_d); | |||||
gf_mlw(b,urr,-EDWARDS_D); | |||||
gf_add(udr2_1,b,ONE); | |||||
gf_mul(a,c,udr2_1); | |||||
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_mul(e,a,c); | |||||
decaf_bool_t square = gf_eq(e,ONE); | |||||
gf_mul(a,b,r); | |||||
cond_sel(b,a,b,square); | |||||
gf_mlw(a,b,EDWARDS_D+1); | |||||
cond_swap(ur2_d,udr2_1,~square); | |||||
gf_mul(e,ur2_d,a); | |||||
cond_neg(e,hibit(e)^square); | |||||
gf_mul(b,udr2_1,a); | |||||
gf_sqr(c,b); | |||||
gf_sqr(a,e); | |||||
gf_sub(a,ONE,a); | |||||
gf_add(e,e,e); | |||||
gf_add(b,dee,c); | |||||
gf_sub(c,dee,c); | |||||
gf_mul(p->x,e,c); | |||||
gf_mul(p->z,a,c); | |||||
gf_mul(p->y,b,a); | |||||
gf_mul(p->t,b,e); | |||||
gf_mlw(c,r,EDWARDS_D); | |||||
/* Compute D := (dr+a-d)(dr-ar-d) with a=1 */ | |||||
gf_sub(a,c,dee); | |||||
gf_add(a,a,ONE); | |||||
gf_sub(b, c, r); | |||||
gf_sub(b, b, dee); | |||||
gf_mul(D,a,b); | |||||
/* compute N := (r+1)(a-2d) with a=1 */ | |||||
gf_add(a,r,ONE); | |||||
gf_mlw(N,a,1-2*EDWARDS_D); | |||||
/* e = +-1/sqrt(+-ND) */ | |||||
gf_mul(a,N,D); | |||||
gf_isqrt(e,a); | |||||
gf_sqr(b,e); | |||||
gf_mul(c,a,b); | |||||
decaf_bool_t square = gf_eq(c,ONE); | |||||
/* *r0 if not square */ | |||||
gf_mul(a,e,r0); | |||||
cond_sel(e,a,e,square); | |||||
cond_neg(e,hibit(e)^~square); | |||||
/* b <- t */ | |||||
gf_mlw(a,e,1-2*EDWARDS_D); | |||||
gf_sqr(b,a); | |||||
gf_mul(a,b,N); | |||||
gf_sub(c,r,ONE); | |||||
gf_mul(b,c,a); | |||||
cond_neg(b,square); | |||||
gf_sub(b,b,ONE); | |||||
/* a <- s */ | |||||
gf_mul(a,e,N); | |||||
/* isogenize */ | |||||
gf_sqr(c,a); /* s^2 */ | |||||
gf_add(a,a,a); /* 2s */ | |||||
gf_add(e,c,ONE); | |||||
gf_mul(p->t,a,e); /* 2s(1+s^2) */ | |||||
gf_mul(p->x,a,b); /* 2st */ | |||||
gf_sub(a,ONE,c); | |||||
gf_mul(p->y,e,a); /* (1+s^2)(1-s^2) */ | |||||
gf_mul(p->z,a,b); /* (1-s^2)t */ | |||||
} | } | ||||
void decaf_448_point_from_hash_uniform ( | void decaf_448_point_from_hash_uniform ( | ||||
@@ -989,39 +989,56 @@ void API_NS(point_from_hash_nonuniform) ( | |||||
point_t p, | point_t p, | ||||
const unsigned char ser[SER_BYTES] | const unsigned char ser[SER_BYTES] | ||||
) { | ) { | ||||
gf r,urr,a,b,c,dee,e,ur2_d,udr2_1; | |||||
(void)gf_deser(r,ser); | |||||
gf_canon(r); | |||||
gf_sqr(a,r); | |||||
/* gf_mlw(urr,a,QUADRATIC_NONRESIDUE); */ | |||||
gf_sub(urr,ZERO,a); | |||||
gf r0,r,a,b,c,dee,D,N,e; | |||||
(void)gf_deser(r0,ser); | |||||
gf_canon(r0); | |||||
gf_sqr(a,r0); | |||||
/*gf_mlw(r,a,QUADRATIC_NONRESIDUE);*/ | |||||
gf_sub(r,ZERO,a); | |||||
gf_mlw(dee,ONE,EDWARDS_D); | gf_mlw(dee,ONE,EDWARDS_D); | ||||
gf_add(a,urr,ONE); | |||||
gf_sub(ur2_d,dee,urr); | |||||
gf_mul(c,a,ur2_d); | |||||
gf_mlw(b,urr,-EDWARDS_D); | |||||
gf_add(udr2_1,b,ONE); | |||||
gf_mul(a,c,udr2_1); | |||||
gf_mlw(c,a,EDWARDS_D+1); | |||||
decaf_bool_t square = gf_isqrt_chk(b,c,DECAF_FALSE); | |||||
/* FIELD: if 5 mod 8, multiply result by u. */ | |||||
gf_mul(a,b,r); | |||||
cond_sel(b,a,b,square); | |||||
gf_mlw(a,b,EDWARDS_D+1); | |||||
cond_swap(ur2_d,udr2_1,~square); | |||||
gf_mul(e,ur2_d,a); | |||||
cond_neg(e,hibit(e)^square); | |||||
gf_mul(b,udr2_1,a); | |||||
gf_sqr(c,b); | |||||
gf_sqr(a,e); | |||||
gf_sub(a,ONE,a); | |||||
gf_add(e,e,e); | |||||
gf_add(b,dee,c); | |||||
gf_sub(c,dee,c); | |||||
gf_mul(p->x,e,c); | |||||
gf_mul(p->z,a,c); | |||||
gf_mul(p->y,b,a); | |||||
gf_mul(p->t,b,e); | |||||
gf_mlw(c,r,EDWARDS_D); | |||||
/* Compute D := (dr+a-d)(dr-ar-d) with a=1 */ | |||||
gf_sub(a,c,dee); | |||||
gf_add(a,a,ONE); | |||||
gf_sub(b,c,r); | |||||
gf_sub(b,b,dee); | |||||
gf_mul(D,a,b); | |||||
/* compute N := (r+1)(a-2d) */ | |||||
gf_add(a,r,ONE); | |||||
gf_mlw(N,a,1-2*EDWARDS_D); | |||||
/* e = +-1/sqrt(+-ND) */ | |||||
gf_mul(a,N,D); | |||||
decaf_bool_t square = gf_isqrt_chk(e,a,DECAF_FALSE); | |||||
/* *r0 if not square */ | |||||
gf_mul(a,e,r0); | |||||
cond_sel(e,a,e,square); | |||||
cond_neg(e,hibit(e)^~square); | |||||
/* b <- t */ | |||||
gf_mlw(a,e,1-2*EDWARDS_D); | |||||
gf_sqr(b,a); | |||||
gf_mul(a,b,N); | |||||
gf_sub(c,r,ONE); | |||||
gf_mul(b,c,a); | |||||
cond_neg(b,square); | |||||
gf_sub(b,b,ONE); | |||||
/* a <- s */ | |||||
gf_mul(a,e,N); | |||||
/* isogenize */ | |||||
gf_sqr(c,a); /* s^2 */ | |||||
gf_add(a,a,a); /* 2s */ | |||||
gf_add(e,c,ONE); | |||||
gf_mul(p->t,a,e); /* 2s(1+s^2) */ | |||||
gf_mul(p->x,a,b); /* 2st */ | |||||
gf_sub(a,ONE,c); | |||||
gf_mul(p->y,e,a); /* (1+s^2)(1-s^2) */ | |||||
gf_mul(p->z,a,b); /* (1-s^2)t */ | |||||
} | } | ||||
void API_NS(point_from_hash_uniform) ( | void API_NS(point_from_hash_uniform) ( | ||||