Commit 2cc6ebfb authored by Michael Hamburg's avatar Michael Hamburg

ed25519 ristretto inverse works except at the identity point

parent 5fc32bf1
......@@ -338,6 +338,7 @@ class Decaf_1_1_Point(QuotientEdwardsPoint):
altx = inum*t*imi
neg_altx = negative(altx) != toggle_altx
if neg_altx != toggle: inum =- inum
tmp = fac*(inum*z + 1)
s = iden*tmp*imi
......@@ -399,7 +400,7 @@ class Decaf_1_1_Point(QuotientEdwardsPoint):
sr *= rnum
if negative(sr) != toggle_r: sr = -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]
rets.append(bytes(ret))
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}}}}};
/* Predeclare because not static: called by elligator */
mask_t API_NS(deisogenize) (
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
......@@ -141,7 +141,7 @@ mask_t API_NS(deisogenize) (
mask_t toggle_rotation
);
mask_t API_NS(deisogenize) (
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
......@@ -150,7 +150,6 @@ mask_t API_NS(deisogenize) (
mask_t toggle_altx,
mask_t toggle_rotation
) {
#if COFACTOR == 4 && !IMAGINE_TWIST
(void)toggle_rotation; /* Only applies to cofactor 8 */
gf t1;
......@@ -177,12 +176,8 @@ mask_t API_NS(deisogenize) (
gf_copy(inv_el_m1,p->x);
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s);
gf_add(inv_el_m1,inv_el_m1,p->t);
return toggle_s;
#elif COFACTOR == 8 && IMAGINE_TWIST
gf_s *altx = inv_el_sum; // TODO
(void)inv_el_m1;
/* More complicated because of rotation */
gf t1,t2,t3,t4,t5;
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(t1,t3,t4); /* t1 = "inum" in ristretto.sage */
/* Calculate altxy = iden*inum*i*t^2*(d-a) */
gf_mul(t3,t1,t2);
gf_mul_qnr(t4,t3);
gf_mul(t3,t4,p->t);
gf_mul(t4,t3,p->t);
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);
/* Rotate if altxy is negative */
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_mul(t2,t1,p->z);
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);
gf_cond_neg(s,negs);
mask_t negz = ~negs ^ toggle_s ^ negx;
gf_copy(inv_el_m1,p->z);
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
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)"
#endif
......@@ -233,7 +231,7 @@ mask_t API_NS(deisogenize) (
void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) {
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);
}
......
......@@ -142,23 +142,21 @@ API_NS(invert_elligator_nonuniform) (
*/
sgn_ed_T = -(hint>>3 & 1);
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);
(void)is_identity;
gf_cond_sel(b,b,ONE,is_identity & sgn_altx);
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx);
#if IMAGINE_TWIST
gf_mulw(a,b,EDWARDS_D);
gf_sub(b,a,b);
gf_mulw(a,b,-EDWARDS_D);
#else
gf_mulw(a,b,EDWARDS_D-1);
gf_add(b,a,b);
#endif
gf_add(b,a,b);
gf_sub(a,a,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(b,c,a);
mask_t succ = gf_isr(c,b);
......@@ -166,10 +164,11 @@ API_NS(invert_elligator_nonuniform) (
gf_mul(b,c,a);
#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;
#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);
// #if COFACTOR == 8
// 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}}}}};
/* Predeclare because not static: called by elligator */
mask_t API_NS(deisogenize) (
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
......@@ -141,7 +141,7 @@ mask_t API_NS(deisogenize) (
mask_t toggle_rotation
);
mask_t API_NS(deisogenize) (
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
......@@ -150,7 +150,6 @@ mask_t API_NS(deisogenize) (
mask_t toggle_altx,
mask_t toggle_rotation
) {
#if COFACTOR == 4 && !IMAGINE_TWIST
(void)toggle_rotation; /* Only applies to cofactor 8 */
gf t1;
......@@ -177,12 +176,8 @@ mask_t API_NS(deisogenize) (
gf_copy(inv_el_m1,p->x);
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s);
gf_add(inv_el_m1,inv_el_m1,p->t);
return toggle_s;
#elif COFACTOR == 8 && IMAGINE_TWIST
gf_s *altx = inv_el_sum; // TODO
(void)inv_el_m1;
/* More complicated because of rotation */
gf t1,t2,t3,t4,t5;
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(t1,t3,t4); /* t1 = "inum" in ristretto.sage */
/* Calculate altxy = iden*inum*i*t^2*(d-a) */
gf_mul(t3,t1,t2);
gf_mul_qnr(t4,t3);
gf_mul(t3,t4,p->t);
gf_mul(t4,t3,p->t);
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);
/* Rotate if altxy is negative */
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_mul(t2,t1,p->z);
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);
gf_cond_neg(s,negs);
mask_t negz = ~negs ^ toggle_s ^ negx;
gf_copy(inv_el_m1,p->z);
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
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)"
#endif
......@@ -233,7 +231,7 @@ mask_t API_NS(deisogenize) (
void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) {
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);
}
......
......@@ -142,23 +142,21 @@ API_NS(invert_elligator_nonuniform) (
*/
sgn_ed_T = -(hint>>3 & 1);
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);
(void)is_identity;
gf_cond_sel(b,b,ONE,is_identity & sgn_altx);
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx);
#if IMAGINE_TWIST
gf_mulw(a,b,EDWARDS_D);
gf_sub(b,a,b);
gf_mulw(a,b,-EDWARDS_D);
#else
gf_mulw(a,b,EDWARDS_D-1);
gf_add(b,a,b);
#endif
gf_add(b,a,b);
gf_sub(a,a,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(b,c,a);
mask_t succ = gf_isr(c,b);
......@@ -166,10 +164,11 @@ API_NS(invert_elligator_nonuniform) (
gf_mul(b,c,a);
#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;
#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);
// #if COFACTOR == 8
// 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}}}}};
/* Predeclare because not static: called by elligator */
mask_t API_NS(deisogenize) (
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
......@@ -130,7 +130,7 @@ mask_t API_NS(deisogenize) (
mask_t toggle_rotation
);
mask_t API_NS(deisogenize) (
void API_NS(deisogenize) (
gf_s *__restrict__ s,
gf_s *__restrict__ inv_el_sum,
gf_s *__restrict__ inv_el_m1,
......@@ -139,7 +139,6 @@ mask_t API_NS(deisogenize) (
mask_t toggle_altx,
mask_t toggle_rotation
) {
#if COFACTOR == 4 && !IMAGINE_TWIST
(void)toggle_rotation; /* Only applies to cofactor 8 */
gf t1;
......@@ -166,12 +165,8 @@ mask_t API_NS(deisogenize) (
gf_copy(inv_el_m1,p->x);
gf_cond_neg(inv_el_m1,~lobs^negx^toggle_s);
gf_add(inv_el_m1,inv_el_m1,p->t);
return toggle_s;
#elif COFACTOR == 8 && IMAGINE_TWIST
gf_s *altx = inv_el_sum; // TODO
(void)inv_el_m1;
/* More complicated because of rotation */
gf t1,t2,t3,t4,t5;
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(t1,t3,t4); /* t1 = "inum" in ristretto.sage */
/* Calculate altxy = iden*inum*i*t^2*(d-a) */
gf_mul(t3,t1,t2);
gf_mul_qnr(t4,t3);
gf_mul(t3,t4,p->t);
gf_mul(t4,t3,p->t);
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);
/* Rotate if altxy is negative */
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_mul(t2,t1,p->z);
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);
gf_cond_neg(s,negs);
mask_t negz = ~negs ^ toggle_s ^ negx;
gf_copy(inv_el_m1,p->z);
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
#error "Cofactor must be 4 (with no IMAGINE_TWIST) or 8 (with IMAGINE_TWIST)"
#endif
......@@ -222,7 +220,7 @@ mask_t API_NS(deisogenize) (
void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) {
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);
}
......
......@@ -131,23 +131,21 @@ API_NS(invert_elligator_nonuniform) (
*/
sgn_ed_T = -(hint>>3 & 1);
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);
(void)is_identity;
gf_cond_sel(b,b,ONE,is_identity & sgn_altx);
gf_cond_sel(c,c,ONE,is_identity & sgn_s &~ sgn_altx);
#if IMAGINE_TWIST
gf_mulw(a,b,EDWARDS_D);
gf_sub(b,a,b);
gf_mulw(a,b,-EDWARDS_D);
#else
gf_mulw(a,b,EDWARDS_D-1);
gf_add(b,a,b);
#endif
gf_add(b,a,b);
gf_sub(a,a,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(b,c,a);
mask_t succ = gf_isr(c,b);
......@@ -155,10 +153,11 @@ API_NS(invert_elligator_nonuniform) (
gf_mul(b,c,a);
#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;
#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);
// #if COFACTOR == 8
// succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment