| @@ -486,7 +486,7 @@ decaf_bool_t decaf_255_point_valid ( | |||||
| * @param [out] q The point to torque. | * @param [out] q The point to torque. | ||||
| * @param [in] p The point to torque. | * @param [in] p The point to torque. | ||||
| */ | */ | ||||
| void decaf_255_point_debugging_2torque ( | |||||
| void decaf_255_point_debugging_torque ( | |||||
| decaf_255_point_t q, | decaf_255_point_t q, | ||||
| const decaf_255_point_t p | const decaf_255_point_t p | ||||
| ) API_VIS NONNULL2 NOINLINE; | ) API_VIS NONNULL2 NOINLINE; | ||||
| @@ -580,7 +580,7 @@ public: | |||||
| } | } | ||||
| inline Point& debugging_torque_in_place() { | inline Point& debugging_torque_in_place() { | ||||
| decaf_255_point_debugging_2torque(p,p); | |||||
| decaf_255_point_debugging_torque(p,p); | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -486,7 +486,7 @@ decaf_bool_t decaf_448_point_valid ( | |||||
| * @param [out] q The point to torque. | * @param [out] q The point to torque. | ||||
| * @param [in] p The point to torque. | * @param [in] p The point to torque. | ||||
| */ | */ | ||||
| void decaf_448_point_debugging_2torque ( | |||||
| void decaf_448_point_debugging_torque ( | |||||
| decaf_448_point_t q, | decaf_448_point_t q, | ||||
| const decaf_448_point_t p | const decaf_448_point_t p | ||||
| ) API_VIS NONNULL2 NOINLINE; | ) API_VIS NONNULL2 NOINLINE; | ||||
| @@ -580,7 +580,7 @@ public: | |||||
| } | } | ||||
| inline Point& debugging_torque_in_place() { | inline Point& debugging_torque_in_place() { | ||||
| decaf_448_point_debugging_2torque(p,p); | |||||
| decaf_448_point_debugging_torque(p,p); | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -891,7 +891,7 @@ decaf_448_invert_elligator_nonuniform ( | |||||
| return succ; | return succ; | ||||
| } | } | ||||
| void decaf_448_point_debugging_2torque ( | |||||
| void decaf_448_point_debugging_torque ( | |||||
| decaf_448_point_t q, | decaf_448_point_t q, | ||||
| const decaf_448_point_t p | const decaf_448_point_t p | ||||
| ) { | ) { | ||||
| @@ -481,7 +481,8 @@ static void deisogenize ( | |||||
| gf_s *__restrict__ minus_t_over_s, | gf_s *__restrict__ minus_t_over_s, | ||||
| const point_t p, | const point_t p, | ||||
| decaf_bool_t toggle_hibit_s, | decaf_bool_t toggle_hibit_s, | ||||
| decaf_bool_t toggle_hibit_t_over_s | |||||
| decaf_bool_t toggle_hibit_t_over_s, | |||||
| decaf_bool_t toggle_rotation | |||||
| ) { | ) { | ||||
| gf c, d, x, t; | gf c, d, x, t; | ||||
| gf_s *b = s, *a = minus_t_over_s; | gf_s *b = s, *a = minus_t_over_s; | ||||
| @@ -514,7 +515,7 @@ static void deisogenize ( | |||||
| * Pink bike shed: frob = zx * 1/tz | * Pink bike shed: frob = zx * 1/tz | ||||
| */ | */ | ||||
| gf_mul ( a, b, c ); /* this is the case for PinkBikeShed */ | gf_mul ( a, b, c ); /* this is the case for PinkBikeShed */ | ||||
| cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate ); | |||||
| cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate^toggle_rotation ); | |||||
| gf_sub ( e, ZERO, x ); | gf_sub ( e, ZERO, x ); | ||||
| cond_sel ( x, p->y, e, rotate ); | cond_sel ( x, p->y, e, rotate ); | ||||
| } | } | ||||
| @@ -534,7 +535,7 @@ static void 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, mtos; | gf s, mtos; | ||||
| deisogenize(s,mtos,p,0,0); | |||||
| deisogenize(s,mtos,p,0,0,0); | |||||
| gf_encode ( ser, s ); | gf_encode ( ser, s ); | ||||
| } | } | ||||
| @@ -1165,7 +1166,7 @@ uint16_t API_NS(point_from_hash_nonuniform) ( | |||||
| assert(API_NS(point_valid)(p)); | assert(API_NS(point_valid)(p)); | ||||
| return (~square & 1) | (sgn_t_over_s & 2) | (sgn_r0 & 4) | (over & 8); | |||||
| return (~square & 1) | (sgn_t_over_s & 2) | (sgn_r0 & 4) | (over & 16); | |||||
| } | } | ||||
| decaf_bool_t | decaf_bool_t | ||||
| @@ -1176,9 +1177,10 @@ API_NS(invert_elligator_nonuniform) ( | |||||
| ) { | ) { | ||||
| decaf_bool_t sgn_s = -(hint & 1), | decaf_bool_t sgn_s = -(hint & 1), | ||||
| sgn_t_over_s = -(hint>>1 & 1), | sgn_t_over_s = -(hint>>1 & 1), | ||||
| sgn_r0 = -(hint>>2 & 1); | |||||
| sgn_r0 = -(hint>>2 & 1), | |||||
| sgn_ed_T = -(hint>>3 & 1); | |||||
| gf a, b, c, d; | gf a, b, c, d; | ||||
| deisogenize(a,c,p,sgn_s,sgn_t_over_s); | |||||
| deisogenize(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T); | |||||
| /* ok, a = s; c = -t/s */ | /* ok, a = s; c = -t/s */ | ||||
| gf_mul(b,c,a); | gf_mul(b,c,a); | ||||
| @@ -1254,14 +1256,23 @@ decaf_bool_t API_NS(point_valid) ( | |||||
| return out; | return out; | ||||
| } | } | ||||
| void API_NS(point_debugging_2torque) ( | |||||
| void API_NS(point_debugging_torque) ( | |||||
| point_t q, | point_t q, | ||||
| const point_t p | const point_t p | ||||
| ) { | ) { | ||||
| #if 0 | |||||
| gf_sub(q->x,ZERO,p->x); | gf_sub(q->x,ZERO,p->x); | ||||
| gf_sub(q->y,ZERO,p->y); | gf_sub(q->y,ZERO,p->y); | ||||
| gf_cpy(q->z,p->z); | gf_cpy(q->z,p->z); | ||||
| gf_cpy(q->t,p->t); | gf_cpy(q->t,p->t); | ||||
| #else | |||||
| gf tmp; | |||||
| gf_mul(tmp,p->x,SQRT_MINUS_ONE); | |||||
| gf_mul(q->x,p->y,SQRT_MINUS_ONE); | |||||
| gf_cpy(q->y,tmp); | |||||
| gf_cpy(q->z,p->z); | |||||
| gf_sub(q->t,ZERO,p->t); | |||||
| #endif | |||||
| } | } | ||||
| static void gf_batch_invert ( | static void gf_batch_invert ( | ||||
| @@ -156,10 +156,10 @@ static void test_elligator() { | |||||
| decaf::SpongeRng rng(decaf::Block("test_elligator")); | decaf::SpongeRng rng(decaf::Block("test_elligator")); | ||||
| Test test("Elligator"); | Test test("Elligator"); | ||||
| for (int i=0; i<16; i++) { | |||||
| for (int i=0; i<32; i++) { | |||||
| decaf::SecureBuffer b1(Point::HASH_BYTES); | decaf::SecureBuffer b1(Point::HASH_BYTES); | ||||
| Point p = Point::identity(); | Point p = Point::identity(); | ||||
| if (i>=8) p.debugging_torque_in_place(); | |||||
| for (int j=0; j<i/8; j++) p.debugging_torque_in_place(); | |||||
| bool succ = p.invert_elligator(b1,i&7); | bool succ = p.invert_elligator(b1,i&7); | ||||
| Point q; | Point q; | ||||
| unsigned char hint = q.set_to_hash(b1); | unsigned char hint = q.set_to_hash(b1); | ||||
| @@ -172,7 +172,7 @@ static void test_elligator() { | |||||
| } | } | ||||
| } | } | ||||
| for (int i=0; i<NTESTS && test.passing_now; i++) { | |||||
| for (int i=0; i<NTESTS && (i<16 || test.passing_now); i++) { | |||||
| size_t len = (i % (2*Point::HASH_BYTES + 3)); | size_t len = (i % (2*Point::HASH_BYTES + 3)); | ||||
| decaf::SecureBuffer b1(len), b2(len); | decaf::SecureBuffer b1(len), b2(len); | ||||
| rng.read(b1); | rng.read(b1); | ||||
| @@ -181,7 +181,7 @@ static void test_elligator() { | |||||
| memcpy(&b2[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES); | memcpy(&b2[Point::HASH_BYTES], &b1[Point::HASH_BYTES], len-Point::HASH_BYTES); | ||||
| Point s; | Point s; | ||||
| unsigned char hint = s.set_to_hash(b1); | unsigned char hint = s.set_to_hash(b1); | ||||
| if (i&1) s.debugging_torque_in_place(); | |||||
| for (int j=0; j<(i&3); j++) s.debugging_torque_in_place(); | |||||
| bool succ = s.invert_elligator(b2,hint); | bool succ = s.invert_elligator(b2,hint); | ||||
| if (!succ || memcmp(b1,b2,len)) { | if (!succ || memcmp(b1,b2,len)) { | ||||
| test.fail(); | test.fail(); | ||||