@@ -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. */ | ||||