| @@ -338,6 +338,7 @@ class Decaf_1_1_Point(QuotientEdwardsPoint): | |||||
| altx = inum*t*imi | altx = inum*t*imi | ||||
| neg_altx = negative(altx) != toggle_altx | neg_altx = negative(altx) != toggle_altx | ||||
| if neg_altx != toggle: inum =- inum | if neg_altx != toggle: inum =- inum | ||||
| tmp = fac*(inum*z + 1) | tmp = fac*(inum*z + 1) | ||||
| s = iden*tmp*imi | s = iden*tmp*imi | ||||
| @@ -399,7 +400,7 @@ class Decaf_1_1_Point(QuotientEdwardsPoint): | |||||
| sr *= rnum | sr *= rnum | ||||
| if negative(sr) != toggle_r: sr = -sr | if negative(sr) != toggle_r: sr = -sr | ||||
| ret = self.gfToBytes(sr) | ret = self.gfToBytes(sr) | ||||
| assert self.elligator(ret) == self or self.elligator(ret) == -self | |||||
| #assert self.elligator(ret) == self or self.elligator(ret) == -self | |||||
| if self.elligator(ret) == -self and self != -self: print "Negated!",[toggle_rotation,toggle_altx,toggle_s,toggle_r] | if self.elligator(ret) == -self and self != -self: print "Negated!",[toggle_rotation,toggle_altx,toggle_s,toggle_r] | ||||
| rets.append(bytes(ret)) | rets.append(bytes(ret)) | ||||
| return rets | return rets | ||||
| @@ -131,7 +131,7 @@ gf_invert(gf y, const gf x, int assert_nonzero) { | |||||
| const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | ||||
| /* Predeclare because not static: called by elligator */ | /* Predeclare because not static: called by elligator */ | ||||
| mask_t API_NS(deisogenize) ( | |||||
| void API_NS(deisogenize) ( | |||||
| gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
| gf_s *__restrict__ inv_el_sum, | gf_s *__restrict__ inv_el_sum, | ||||
| gf_s *__restrict__ inv_el_m1, | gf_s *__restrict__ inv_el_m1, | ||||
| @@ -141,7 +141,7 @@ mask_t API_NS(deisogenize) ( | |||||
| mask_t toggle_rotation | mask_t toggle_rotation | ||||
| ); | ); | ||||
| mask_t API_NS(deisogenize) ( | |||||
| void API_NS(deisogenize) ( | |||||
| gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
| gf_s *__restrict__ inv_el_sum, | gf_s *__restrict__ inv_el_sum, | ||||
| gf_s *__restrict__ inv_el_m1, | gf_s *__restrict__ inv_el_m1, | ||||
| @@ -150,7 +150,6 @@ mask_t API_NS(deisogenize) ( | |||||
| mask_t toggle_altx, | mask_t toggle_altx, | ||||
| mask_t toggle_rotation | mask_t toggle_rotation | ||||
| ) { | ) { | ||||
| #if COFACTOR == 4 && !IMAGINE_TWIST | #if COFACTOR == 4 && !IMAGINE_TWIST | ||||
| (void)toggle_rotation; /* Only applies to cofactor 8 */ | (void)toggle_rotation; /* Only applies to cofactor 8 */ | ||||
| gf t1; | gf t1; | ||||
| @@ -177,12 +176,8 @@ mask_t API_NS(deisogenize) ( | |||||
| gf_copy(inv_el_m1,p->x); | gf_copy(inv_el_m1,p->x); | ||||
| gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | ||||
| gf_add(inv_el_m1,inv_el_m1,p->t); | gf_add(inv_el_m1,inv_el_m1,p->t); | ||||
| return toggle_s; | |||||
| #elif COFACTOR == 8 && IMAGINE_TWIST | #elif COFACTOR == 8 && IMAGINE_TWIST | ||||
| gf_s *altx = inv_el_sum; // TODO | |||||
| (void)inv_el_m1; | |||||
| /* More complicated because of rotation */ | /* More complicated because of rotation */ | ||||
| gf t1,t2,t3,t4,t5; | gf t1,t2,t3,t4,t5; | ||||
| gf_add(t1,p->z,p->y); | gf_add(t1,p->z,p->y); | ||||
| @@ -197,35 +192,38 @@ mask_t API_NS(deisogenize) ( | |||||
| gf_mul(t2,t1,RISTRETTO_ISOMAGIC); /* t2 = "iden" in ristretto.sage */ | gf_mul(t2,t1,RISTRETTO_ISOMAGIC); /* t2 = "iden" in ristretto.sage */ | ||||
| gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */ | gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */ | ||||
| /* Calculate altxy = iden*inum*i*t^2*(d-a) */ | |||||
| gf_mul(t3,t1,t2); | gf_mul(t3,t1,t2); | ||||
| gf_mul_qnr(t4,t3); | gf_mul_qnr(t4,t3); | ||||
| gf_mul(t3,t4,p->t); | gf_mul(t3,t4,p->t); | ||||
| gf_mul(t4,t3,p->t); | gf_mul(t4,t3,p->t); | ||||
| gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */ | gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */ | ||||
| gf_mul_qnr(t4,p->x); | |||||
| mask_t rotate = toggle_rotation ^ gf_lobit(t3); | mask_t rotate = toggle_rotation ^ gf_lobit(t3); | ||||
| /* Rotate if altxy is negative */ | |||||
| gf_cond_swap(t1,t2,rotate); | gf_cond_swap(t1,t2,rotate); | ||||
| gf_cond_sel(t4,p->y,t4,rotate); /* "fac" = ix if rotate, else y */ | |||||
| gf_mul(t3,t2,t4); /* "fac*iden" */ | |||||
| gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | |||||
| gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | |||||
| gf_mul(t5,t2,p->t); | |||||
| gf_mul(altx,t5,t1); | |||||
| mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
| gf_mul_qnr(t4,p->x); | |||||
| gf_cond_sel(t4,p->y,t4,rotate); /* t4 = "fac" = ix if rotate, else y */ | |||||
| gf_mul_qnr(t5,RISTRETTO_ISOMAGIC); /* t5 = imi */ | |||||
| gf_mul(t3,t5,t2); /* iden * imi */ | |||||
| gf_mul(t2,t5,t1); | |||||
| gf_mul(t5,t2,p->t); /* "altx" = iden*imi*t */ | |||||
| mask_t negx = gf_lobit(t5) ^ toggle_altx; | |||||
| gf_cond_neg(t1,negx^rotate); | gf_cond_neg(t1,negx^rotate); | ||||
| gf_mul(t2,t1,p->z); | gf_mul(t2,t1,p->z); | ||||
| gf_add(t2,t2,ONE); | gf_add(t2,t2,ONE); | ||||
| gf_mul(s,t2,t4); | |||||
| gf_mul(inv_el_sum,t2,t4); | |||||
| gf_mul(s,inv_el_sum,t3); | |||||
| mask_t negs = gf_lobit(s); | mask_t negs = gf_lobit(s); | ||||
| gf_cond_neg(s,negs); | gf_cond_neg(s,negs); | ||||
| mask_t negz = ~negs ^ toggle_s ^ negx; | mask_t negz = ~negs ^ toggle_s ^ negx; | ||||
| gf_copy(inv_el_m1,p->z); | gf_copy(inv_el_m1,p->z); | ||||
| gf_cond_neg(inv_el_m1,negz); | gf_cond_neg(inv_el_m1,negz); | ||||
| gf_sub(inv_el_m1,inv_el_m1,t3); | |||||
| return toggle_s; | |||||
| gf_sub(inv_el_m1,inv_el_m1,t4); | |||||
| #else | #else | ||||
| #error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | #error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | ||||
| #endif | #endif | ||||
| @@ -233,7 +231,7 @@ mask_t API_NS(deisogenize) ( | |||||
| void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | ||||
| gf s,ie1,ie2; | gf s,ie1,ie2; | ||||
| (void)API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
| API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
| gf_serialize(ser,s,1); | gf_serialize(ser,s,1); | ||||
| } | } | ||||
| @@ -142,23 +142,21 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| */ | */ | ||||
| sgn_ed_T = -(hint>>3 & 1); | sgn_ed_T = -(hint>>3 & 1); | ||||
| gf a,b,c; | gf a,b,c; | ||||
| mask_t swap = API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
| API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
| mask_t is_identity = gf_eq(p->t,ZERO); | mask_t is_identity = gf_eq(p->t,ZERO); | ||||
| (void)is_identity; | |||||
| gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | ||||
| gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | ||||
| #if IMAGINE_TWIST | #if IMAGINE_TWIST | ||||
| gf_mulw(a,b,EDWARDS_D); | |||||
| gf_sub(b,a,b); | |||||
| gf_mulw(a,b,-EDWARDS_D); | |||||
| #else | #else | ||||
| gf_mulw(a,b,EDWARDS_D-1); | gf_mulw(a,b,EDWARDS_D-1); | ||||
| gf_add(b,a,b); | |||||
| #endif | #endif | ||||
| gf_add(b,a,b); | |||||
| gf_sub(a,a,c); | gf_sub(a,a,c); | ||||
| gf_add(b,b,c); | gf_add(b,b,c); | ||||
| gf_cond_swap(a,b,swap); | |||||
| gf_cond_swap(a,b,sgn_s); | |||||
| gf_mul_qnr(c,b); | gf_mul_qnr(c,b); | ||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| mask_t succ = gf_isr(c,b); | mask_t succ = gf_isr(c,b); | ||||
| @@ -166,10 +164,11 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| #if 255 == 8*SER_BYTES + 1 /* p521. */ | #if 255 == 8*SER_BYTES + 1 /* p521. */ | ||||
| #error "this won't work because it needs to adjust high bit, not low bit" | |||||
| sgn_r0 = 0; | sgn_r0 = 0; | ||||
| #endif | #endif | ||||
| gf_cond_neg(b, sgn_r0^gf_hibit(b)); | |||||
| gf_cond_neg(b, sgn_r0^gf_lobit(b)); | |||||
| succ &= ~(gf_eq(b,ZERO) & sgn_r0); | succ &= ~(gf_eq(b,ZERO) & sgn_r0); | ||||
| // #if COFACTOR == 8 | // #if COFACTOR == 8 | ||||
| // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | ||||
| @@ -131,7 +131,7 @@ gf_invert(gf y, const gf x, int assert_nonzero) { | |||||
| const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | ||||
| /* Predeclare because not static: called by elligator */ | /* Predeclare because not static: called by elligator */ | ||||
| mask_t API_NS(deisogenize) ( | |||||
| void API_NS(deisogenize) ( | |||||
| gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
| gf_s *__restrict__ inv_el_sum, | gf_s *__restrict__ inv_el_sum, | ||||
| gf_s *__restrict__ inv_el_m1, | gf_s *__restrict__ inv_el_m1, | ||||
| @@ -141,7 +141,7 @@ mask_t API_NS(deisogenize) ( | |||||
| mask_t toggle_rotation | mask_t toggle_rotation | ||||
| ); | ); | ||||
| mask_t API_NS(deisogenize) ( | |||||
| void API_NS(deisogenize) ( | |||||
| gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
| gf_s *__restrict__ inv_el_sum, | gf_s *__restrict__ inv_el_sum, | ||||
| gf_s *__restrict__ inv_el_m1, | gf_s *__restrict__ inv_el_m1, | ||||
| @@ -150,7 +150,6 @@ mask_t API_NS(deisogenize) ( | |||||
| mask_t toggle_altx, | mask_t toggle_altx, | ||||
| mask_t toggle_rotation | mask_t toggle_rotation | ||||
| ) { | ) { | ||||
| #if COFACTOR == 4 && !IMAGINE_TWIST | #if COFACTOR == 4 && !IMAGINE_TWIST | ||||
| (void)toggle_rotation; /* Only applies to cofactor 8 */ | (void)toggle_rotation; /* Only applies to cofactor 8 */ | ||||
| gf t1; | gf t1; | ||||
| @@ -177,12 +176,8 @@ mask_t API_NS(deisogenize) ( | |||||
| gf_copy(inv_el_m1,p->x); | gf_copy(inv_el_m1,p->x); | ||||
| gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | ||||
| gf_add(inv_el_m1,inv_el_m1,p->t); | gf_add(inv_el_m1,inv_el_m1,p->t); | ||||
| return toggle_s; | |||||
| #elif COFACTOR == 8 && IMAGINE_TWIST | #elif COFACTOR == 8 && IMAGINE_TWIST | ||||
| gf_s *altx = inv_el_sum; // TODO | |||||
| (void)inv_el_m1; | |||||
| /* More complicated because of rotation */ | /* More complicated because of rotation */ | ||||
| gf t1,t2,t3,t4,t5; | gf t1,t2,t3,t4,t5; | ||||
| gf_add(t1,p->z,p->y); | gf_add(t1,p->z,p->y); | ||||
| @@ -197,35 +192,38 @@ mask_t API_NS(deisogenize) ( | |||||
| gf_mul(t2,t1,RISTRETTO_ISOMAGIC); /* t2 = "iden" in ristretto.sage */ | gf_mul(t2,t1,RISTRETTO_ISOMAGIC); /* t2 = "iden" in ristretto.sage */ | ||||
| gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */ | gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */ | ||||
| /* Calculate altxy = iden*inum*i*t^2*(d-a) */ | |||||
| gf_mul(t3,t1,t2); | gf_mul(t3,t1,t2); | ||||
| gf_mul_qnr(t4,t3); | gf_mul_qnr(t4,t3); | ||||
| gf_mul(t3,t4,p->t); | gf_mul(t3,t4,p->t); | ||||
| gf_mul(t4,t3,p->t); | gf_mul(t4,t3,p->t); | ||||
| gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */ | gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */ | ||||
| gf_mul_qnr(t4,p->x); | |||||
| mask_t rotate = toggle_rotation ^ gf_lobit(t3); | mask_t rotate = toggle_rotation ^ gf_lobit(t3); | ||||
| /* Rotate if altxy is negative */ | |||||
| gf_cond_swap(t1,t2,rotate); | gf_cond_swap(t1,t2,rotate); | ||||
| gf_cond_sel(t4,p->y,t4,rotate); /* "fac" = ix if rotate, else y */ | |||||
| gf_mul(t3,t2,t4); /* "fac*iden" */ | |||||
| gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | |||||
| gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | |||||
| gf_mul(t5,t2,p->t); | |||||
| gf_mul(altx,t5,t1); | |||||
| mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
| gf_mul_qnr(t4,p->x); | |||||
| gf_cond_sel(t4,p->y,t4,rotate); /* t4 = "fac" = ix if rotate, else y */ | |||||
| gf_mul_qnr(t5,RISTRETTO_ISOMAGIC); /* t5 = imi */ | |||||
| gf_mul(t3,t5,t2); /* iden * imi */ | |||||
| gf_mul(t2,t5,t1); | |||||
| gf_mul(t5,t2,p->t); /* "altx" = iden*imi*t */ | |||||
| mask_t negx = gf_lobit(t5) ^ toggle_altx; | |||||
| gf_cond_neg(t1,negx^rotate); | gf_cond_neg(t1,negx^rotate); | ||||
| gf_mul(t2,t1,p->z); | gf_mul(t2,t1,p->z); | ||||
| gf_add(t2,t2,ONE); | gf_add(t2,t2,ONE); | ||||
| gf_mul(s,t2,t4); | |||||
| gf_mul(inv_el_sum,t2,t4); | |||||
| gf_mul(s,inv_el_sum,t3); | |||||
| mask_t negs = gf_lobit(s); | mask_t negs = gf_lobit(s); | ||||
| gf_cond_neg(s,negs); | gf_cond_neg(s,negs); | ||||
| mask_t negz = ~negs ^ toggle_s ^ negx; | mask_t negz = ~negs ^ toggle_s ^ negx; | ||||
| gf_copy(inv_el_m1,p->z); | gf_copy(inv_el_m1,p->z); | ||||
| gf_cond_neg(inv_el_m1,negz); | gf_cond_neg(inv_el_m1,negz); | ||||
| gf_sub(inv_el_m1,inv_el_m1,t3); | |||||
| return toggle_s; | |||||
| gf_sub(inv_el_m1,inv_el_m1,t4); | |||||
| #else | #else | ||||
| #error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | #error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | ||||
| #endif | #endif | ||||
| @@ -233,7 +231,7 @@ mask_t API_NS(deisogenize) ( | |||||
| void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | ||||
| gf s,ie1,ie2; | gf s,ie1,ie2; | ||||
| (void)API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
| API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
| gf_serialize(ser,s,1); | gf_serialize(ser,s,1); | ||||
| } | } | ||||
| @@ -142,23 +142,21 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| */ | */ | ||||
| sgn_ed_T = -(hint>>3 & 1); | sgn_ed_T = -(hint>>3 & 1); | ||||
| gf a,b,c; | gf a,b,c; | ||||
| mask_t swap = API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
| API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
| mask_t is_identity = gf_eq(p->t,ZERO); | mask_t is_identity = gf_eq(p->t,ZERO); | ||||
| (void)is_identity; | |||||
| gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | ||||
| gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | ||||
| #if IMAGINE_TWIST | #if IMAGINE_TWIST | ||||
| gf_mulw(a,b,EDWARDS_D); | |||||
| gf_sub(b,a,b); | |||||
| gf_mulw(a,b,-EDWARDS_D); | |||||
| #else | #else | ||||
| gf_mulw(a,b,EDWARDS_D-1); | gf_mulw(a,b,EDWARDS_D-1); | ||||
| gf_add(b,a,b); | |||||
| #endif | #endif | ||||
| gf_add(b,a,b); | |||||
| gf_sub(a,a,c); | gf_sub(a,a,c); | ||||
| gf_add(b,b,c); | gf_add(b,b,c); | ||||
| gf_cond_swap(a,b,swap); | |||||
| gf_cond_swap(a,b,sgn_s); | |||||
| gf_mul_qnr(c,b); | gf_mul_qnr(c,b); | ||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| mask_t succ = gf_isr(c,b); | mask_t succ = gf_isr(c,b); | ||||
| @@ -166,10 +164,11 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| #if 448 == 8*SER_BYTES + 1 /* p521. */ | #if 448 == 8*SER_BYTES + 1 /* p521. */ | ||||
| #error "this won't work because it needs to adjust high bit, not low bit" | |||||
| sgn_r0 = 0; | sgn_r0 = 0; | ||||
| #endif | #endif | ||||
| gf_cond_neg(b, sgn_r0^gf_hibit(b)); | |||||
| gf_cond_neg(b, sgn_r0^gf_lobit(b)); | |||||
| succ &= ~(gf_eq(b,ZERO) & sgn_r0); | succ &= ~(gf_eq(b,ZERO) & sgn_r0); | ||||
| // #if COFACTOR == 8 | // #if COFACTOR == 8 | ||||
| // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | ||||
| @@ -120,7 +120,7 @@ gf_invert(gf y, const gf x, int assert_nonzero) { | |||||
| const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; | ||||
| /* Predeclare because not static: called by elligator */ | /* Predeclare because not static: called by elligator */ | ||||
| mask_t API_NS(deisogenize) ( | |||||
| void API_NS(deisogenize) ( | |||||
| gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
| gf_s *__restrict__ inv_el_sum, | gf_s *__restrict__ inv_el_sum, | ||||
| gf_s *__restrict__ inv_el_m1, | gf_s *__restrict__ inv_el_m1, | ||||
| @@ -130,7 +130,7 @@ mask_t API_NS(deisogenize) ( | |||||
| mask_t toggle_rotation | mask_t toggle_rotation | ||||
| ); | ); | ||||
| mask_t API_NS(deisogenize) ( | |||||
| void API_NS(deisogenize) ( | |||||
| gf_s *__restrict__ s, | gf_s *__restrict__ s, | ||||
| gf_s *__restrict__ inv_el_sum, | gf_s *__restrict__ inv_el_sum, | ||||
| gf_s *__restrict__ inv_el_m1, | gf_s *__restrict__ inv_el_m1, | ||||
| @@ -139,7 +139,6 @@ mask_t API_NS(deisogenize) ( | |||||
| mask_t toggle_altx, | mask_t toggle_altx, | ||||
| mask_t toggle_rotation | mask_t toggle_rotation | ||||
| ) { | ) { | ||||
| #if COFACTOR == 4 && !IMAGINE_TWIST | #if COFACTOR == 4 && !IMAGINE_TWIST | ||||
| (void)toggle_rotation; /* Only applies to cofactor 8 */ | (void)toggle_rotation; /* Only applies to cofactor 8 */ | ||||
| gf t1; | gf t1; | ||||
| @@ -166,12 +165,8 @@ mask_t API_NS(deisogenize) ( | |||||
| gf_copy(inv_el_m1,p->x); | gf_copy(inv_el_m1,p->x); | ||||
| gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s); | ||||
| gf_add(inv_el_m1,inv_el_m1,p->t); | gf_add(inv_el_m1,inv_el_m1,p->t); | ||||
| return toggle_s; | |||||
| #elif COFACTOR == 8 && IMAGINE_TWIST | #elif COFACTOR == 8 && IMAGINE_TWIST | ||||
| gf_s *altx = inv_el_sum; // TODO | |||||
| (void)inv_el_m1; | |||||
| /* More complicated because of rotation */ | /* More complicated because of rotation */ | ||||
| gf t1,t2,t3,t4,t5; | gf t1,t2,t3,t4,t5; | ||||
| gf_add(t1,p->z,p->y); | gf_add(t1,p->z,p->y); | ||||
| @@ -186,35 +181,38 @@ mask_t API_NS(deisogenize) ( | |||||
| gf_mul(t2,t1,RISTRETTO_ISOMAGIC); /* t2 = "iden" in ristretto.sage */ | gf_mul(t2,t1,RISTRETTO_ISOMAGIC); /* t2 = "iden" in ristretto.sage */ | ||||
| gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */ | gf_mul(t1,t3,t4); /* t1 = "inum" in ristretto.sage */ | ||||
| /* Calculate altxy = iden*inum*i*t^2*(d-a) */ | |||||
| gf_mul(t3,t1,t2); | gf_mul(t3,t1,t2); | ||||
| gf_mul_qnr(t4,t3); | gf_mul_qnr(t4,t3); | ||||
| gf_mul(t3,t4,p->t); | gf_mul(t3,t4,p->t); | ||||
| gf_mul(t4,t3,p->t); | gf_mul(t4,t3,p->t); | ||||
| gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */ | gf_mulw(t3,t4,TWISTED_D+1); /* iden*inum*i*t^2*(d-1) */ | ||||
| gf_mul_qnr(t4,p->x); | |||||
| mask_t rotate = toggle_rotation ^ gf_lobit(t3); | mask_t rotate = toggle_rotation ^ gf_lobit(t3); | ||||
| /* Rotate if altxy is negative */ | |||||
| gf_cond_swap(t1,t2,rotate); | gf_cond_swap(t1,t2,rotate); | ||||
| gf_cond_sel(t4,p->y,t4,rotate); /* "fac" = ix if rotate, else y */ | |||||
| gf_mul(t3,t2,t4); /* "fac*iden" */ | |||||
| gf_mul_qnr(t2,RISTRETTO_ISOMAGIC); | |||||
| gf_mul(t4,t2,t3); /* "fac*iden*imi" */ | |||||
| gf_mul(t5,t2,p->t); | |||||
| gf_mul(altx,t5,t1); | |||||
| mask_t negx = gf_lobit(altx) ^ toggle_altx; | |||||
| gf_mul_qnr(t4,p->x); | |||||
| gf_cond_sel(t4,p->y,t4,rotate); /* t4 = "fac" = ix if rotate, else y */ | |||||
| gf_mul_qnr(t5,RISTRETTO_ISOMAGIC); /* t5 = imi */ | |||||
| gf_mul(t3,t5,t2); /* iden * imi */ | |||||
| gf_mul(t2,t5,t1); | |||||
| gf_mul(t5,t2,p->t); /* "altx" = iden*imi*t */ | |||||
| mask_t negx = gf_lobit(t5) ^ toggle_altx; | |||||
| gf_cond_neg(t1,negx^rotate); | gf_cond_neg(t1,negx^rotate); | ||||
| gf_mul(t2,t1,p->z); | gf_mul(t2,t1,p->z); | ||||
| gf_add(t2,t2,ONE); | gf_add(t2,t2,ONE); | ||||
| gf_mul(s,t2,t4); | |||||
| gf_mul(inv_el_sum,t2,t4); | |||||
| gf_mul(s,inv_el_sum,t3); | |||||
| mask_t negs = gf_lobit(s); | mask_t negs = gf_lobit(s); | ||||
| gf_cond_neg(s,negs); | gf_cond_neg(s,negs); | ||||
| mask_t negz = ~negs ^ toggle_s ^ negx; | mask_t negz = ~negs ^ toggle_s ^ negx; | ||||
| gf_copy(inv_el_m1,p->z); | gf_copy(inv_el_m1,p->z); | ||||
| gf_cond_neg(inv_el_m1,negz); | gf_cond_neg(inv_el_m1,negz); | ||||
| gf_sub(inv_el_m1,inv_el_m1,t3); | |||||
| return toggle_s; | |||||
| gf_sub(inv_el_m1,inv_el_m1,t4); | |||||
| #else | #else | ||||
| #error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | #error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)" | ||||
| #endif | #endif | ||||
| @@ -222,7 +220,7 @@ mask_t API_NS(deisogenize) ( | |||||
| void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { | ||||
| gf s,ie1,ie2; | gf s,ie1,ie2; | ||||
| (void)API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
| API_NS(deisogenize)(s,ie1,ie2,p,0,0,0); | |||||
| gf_serialize(ser,s,1); | gf_serialize(ser,s,1); | ||||
| } | } | ||||
| @@ -131,23 +131,21 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| */ | */ | ||||
| sgn_ed_T = -(hint>>3 & 1); | sgn_ed_T = -(hint>>3 & 1); | ||||
| gf a,b,c; | gf a,b,c; | ||||
| mask_t swap = API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
| API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); | |||||
| mask_t is_identity = gf_eq(p->t,ZERO); | mask_t is_identity = gf_eq(p->t,ZERO); | ||||
| (void)is_identity; | |||||
| gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | gf_cond_sel(b,b,ONE,is_identity & sgn_altx); | ||||
| gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx); | ||||
| #if IMAGINE_TWIST | #if IMAGINE_TWIST | ||||
| gf_mulw(a,b,EDWARDS_D); | |||||
| gf_sub(b,a,b); | |||||
| gf_mulw(a,b,-EDWARDS_D); | |||||
| #else | #else | ||||
| gf_mulw(a,b,EDWARDS_D-1); | gf_mulw(a,b,EDWARDS_D-1); | ||||
| gf_add(b,a,b); | |||||
| #endif | #endif | ||||
| gf_add(b,a,b); | |||||
| gf_sub(a,a,c); | gf_sub(a,a,c); | ||||
| gf_add(b,b,c); | gf_add(b,b,c); | ||||
| gf_cond_swap(a,b,swap); | |||||
| gf_cond_swap(a,b,sgn_s); | |||||
| gf_mul_qnr(c,b); | gf_mul_qnr(c,b); | ||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| mask_t succ = gf_isr(c,b); | mask_t succ = gf_isr(c,b); | ||||
| @@ -155,10 +153,11 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| #if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */ | #if $(gf_bits) == 8*SER_BYTES + 1 /* p521. */ | ||||
| #error "this won't work because it needs to adjust high bit, not low bit" | |||||
| sgn_r0 = 0; | sgn_r0 = 0; | ||||
| #endif | #endif | ||||
| gf_cond_neg(b, sgn_r0^gf_hibit(b)); | |||||
| gf_cond_neg(b, sgn_r0^gf_lobit(b)); | |||||
| succ &= ~(gf_eq(b,ZERO) & sgn_r0); | succ &= ~(gf_eq(b,ZERO) & sgn_r0); | ||||
| // #if COFACTOR == 8 | // #if COFACTOR == 8 | ||||
| // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | // succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ | ||||