diff --git a/src/decaf_fast.c b/src/decaf_fast.c index dc328a8..b425eb3 100644 --- a/src/decaf_fast.c +++ b/src/decaf_fast.c @@ -478,8 +478,15 @@ static void gf_encode ( unsigned char ser[SER_BYTES], gf a ) { extern const gf SQRT_MINUS_ONE; /* Intern this? */ -void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { - gf a, b, c, d, x, t; +static void deisogenize ( + gf_s *__restrict__ s, + gf_s *__restrict__ minus_t_over_s, + const point_t p, + decaf_bool_t toggle_hibit_s, + decaf_bool_t toggle_hibit_t_over_s +) { + gf a, d, x, t; + gf_s *b = s, *c = minus_t_over_s; /* TODO: intern below */ gf_mul ( x, p->x, SQRT_MINUS_ONE); @@ -505,36 +512,19 @@ void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { gf_mul ( c, a, d ); // new "osx" gf_mul ( a, c, p->z ); gf_add ( a, a, a ); // 2 * "osx" * Z - cond_neg ( c, ~hibit(a) ); + decaf_bool_t tg1 = toggle_hibit_t_over_s ^~ hibit(a); + cond_neg ( c, tg1 ); + cond_neg ( a, tg1 ); gf_mul ( a, b, p->z ); gf_add ( a, a, c ); gf_mul ( b, a, p->y ); - cond_neg ( b, hibit(b) ); - gf_encode ( ser, b ); + cond_neg ( b, toggle_hibit_s ^ hibit(b) ); +} -#if 0 - /* Can shave off one mul here; not important but makes consistent with paper */ - gf a, b, c, d; - gf_mlw ( a, p->y, 1-EDWARDS_D ); - gf_mul ( c, a, p->t ); /* -dYT, with EDWARDS_D = d-1 */ - gf_mul ( a, p->x, p->z ); - gf_sub ( d, c, a ); /* aXZ-dYT with a=-1 */ - gf_add ( a, p->z, p->y ); - gf_sub ( b, p->z, p->y ); - gf_mul ( c, b, a ); - gf_mlw ( b, c, -EDWARDS_D ); /* (a-d)(Z+Y)(Z-Y) */ - gf_isqrt ( a, b ); /* r in the paper */ - gf_mlw ( b, a, -EDWARDS_D ); /* u in the paper */ - gf_mul ( c, b, a ); /* ur */ - gf_mul ( a, c, d ); /* ur (aZX-dYT) */ - gf_add ( d, b, b ); /* 2u = -2au since a=-1 */ - gf_mul ( c, d, p->z ); /* 2uZ */ - cond_neg ( b, ~hibit(c) ); /* u <- -u if negative. */ - gf_mul ( c, b, p->y ); - gf_add ( a, a, c ); - cond_neg ( a, hibit(a) ); - gf_encode(ser, a); -#endif +void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { + gf s, mtos; + deisogenize(s,mtos,p,0,0); + gf_encode ( ser, s ); } /** @@ -1174,25 +1164,7 @@ API_NS(invert_elligator_nonuniform) ( sgn_t_over_s = -(hint>>1 & 1), sgn_r0 = -(hint>>2 & 1); gf a, b, c, d; - gf_mlw ( a, p->y, 1-EDWARDS_D ); - gf_mul ( c, a, p->t ); - gf_mul ( a, p->x, p->z ); - gf_sub ( d, c, a ); - gf_add ( a, p->z, p->y ); - gf_sub ( b, p->z, p->y ); - gf_mul ( c, b, a ); - gf_mlw ( b, c, -EDWARDS_D ); - gf_isqrt ( a, b ); - gf_mlw ( b, a, -EDWARDS_D ); - gf_mul ( c, b, a ); - gf_mul ( a, c, d ); - gf_add ( d, b, b ); - gf_mul ( c, d, p->z ); - cond_neg ( b, sgn_t_over_s^~hibit(c) ); - cond_neg ( c, sgn_t_over_s^~hibit(c) ); - gf_mul ( d, b, p->y ); - gf_add ( a, a, d ); - cond_neg( a, hibit(a)^sgn_s); + deisogenize(a,c,p,sgn_s,sgn_t_over_s); /* ok, a = s; c = -t/s */ gf_mul(b,c,a); @@ -1208,11 +1180,12 @@ API_NS(invert_elligator_nonuniform) ( } gf_mlw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */ - gf_add(a,b,d); /* num? */ - gf_sub(d,b,d); /* den? */ + gf_add(a,d,b); /* num? */ + gf_sub(d,d,b); /* den? */ gf_mul(b,a,d); /* n*d */ cond_sel(a,d,a,sgn_s); - decaf_bool_t succ = gf_isqrt_chk(c,b,DECAF_TRUE); + gf_mul(d,b,SQRT_MINUS_ONE); + decaf_bool_t succ = gf_isqrt_chk(c,d,DECAF_TRUE); gf_mul(b,a,c); cond_neg(b, sgn_r0^hibit(b)); diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index 4f904b5..1f90c6e 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -163,7 +163,7 @@ static void test_elligator() { bool succ = p.invert_elligator(b1,i&7); Point q; unsigned char hint = q.set_to_hash(b1); - + if (succ != ((i&7) != 4) || (q != p) || (succ && (hint != (i&7)))) { test.fail(); printf("Elligator test: t=%d, h=%d->%d, q%sp, %s %02x%02x\n", @@ -172,7 +172,7 @@ static void test_elligator() { } } - for (int i=0; i