From 2cc6ebfb67aa49244fdea94b8bb4a1319ef9404a Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Thu, 5 Oct 2017 20:37:30 -0700 Subject: [PATCH] ed25519 ristretto inverse works except at the identity point --- aux/ristretto/ristretto.sage | 3 +- src/GENERATED/c/curve25519/decaf.c | 38 ++++++++++----------- src/GENERATED/c/curve25519/elligator.c | 13 ++++--- src/GENERATED/c/ed448goldilocks/decaf.c | 38 ++++++++++----------- src/GENERATED/c/ed448goldilocks/elligator.c | 13 ++++--- src/per_curve/decaf.tmpl.c | 38 ++++++++++----------- src/per_curve/elligator.tmpl.c | 13 ++++--- 7 files changed, 74 insertions(+), 82 deletions(-) diff --git a/aux/ristretto/ristretto.sage b/aux/ristretto/ristretto.sage index 3f442d5..b5ed04a 100644 --- a/aux/ristretto/ristretto.sage +++ b/aux/ristretto/ristretto.sage @@ -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 diff --git a/src/GENERATED/c/curve25519/decaf.c b/src/GENERATED/c/curve25519/decaf.c index 36ca9ec..7a66b3f 100644 --- a/src/GENERATED/c/curve25519/decaf.c +++ b/src/GENERATED/c/curve25519/decaf.c @@ -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); } diff --git a/src/GENERATED/c/curve25519/elligator.c b/src/GENERATED/c/curve25519/elligator.c index 0511d23..ec1ffce 100644 --- a/src/GENERATED/c/curve25519/elligator.c +++ b/src/GENERATED/c/curve25519/elligator.c @@ -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. */ diff --git a/src/GENERATED/c/ed448goldilocks/decaf.c b/src/GENERATED/c/ed448goldilocks/decaf.c index e3c46b2..dedc3cc 100644 --- a/src/GENERATED/c/ed448goldilocks/decaf.c +++ b/src/GENERATED/c/ed448goldilocks/decaf.c @@ -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); } diff --git a/src/GENERATED/c/ed448goldilocks/elligator.c b/src/GENERATED/c/ed448goldilocks/elligator.c index feb3bb1..d691a06 100644 --- a/src/GENERATED/c/ed448goldilocks/elligator.c +++ b/src/GENERATED/c/ed448goldilocks/elligator.c @@ -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. */ diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index 6da0bfa..49fe6db 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -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); } diff --git a/src/per_curve/elligator.tmpl.c b/src/per_curve/elligator.tmpl.c index 747f361..342aa53 100644 --- a/src/per_curve/elligator.tmpl.c +++ b/src/per_curve/elligator.tmpl.c @@ -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. */